annotate multimerge.py @ 119:f671602635b7

Rename some objects and variables.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 18 Oct 2016 14:39:59 +0300
parents 591cc558bbcd
children 1f7967aa0133
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
1 #!/usr/bin/python
3
1e254756d0a5 Our code is UTF-8 Unicode.
Matti Hamalainen <ccr@tnsp.org>
parents: 2
diff changeset
2 # coding=utf-8
2
34c3a08a4a37 Copyright, etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 1
diff changeset
3 ###
36
2d7767f0fb67 Remove version.
Matti Hamalainen <ccr@tnsp.org>
parents: 35
diff changeset
4 ### Google Calendar MultiMerge
80
4bed40e35fae Fix copyright and add information about license.
Matti Hamalainen <ccr@tnsp.org>
parents: 78
diff changeset
5 ### Programmed and designed by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
4bed40e35fae Fix copyright and add information about license.
Matti Hamalainen <ccr@tnsp.org>
parents: 78
diff changeset
6 ### (C) Copyright 2016 Tecnic Software productions (TNSP)
4bed40e35fae Fix copyright and add information about license.
Matti Hamalainen <ccr@tnsp.org>
parents: 78
diff changeset
7 ###
4bed40e35fae Fix copyright and add information about license.
Matti Hamalainen <ccr@tnsp.org>
parents: 78
diff changeset
8 ### For license information, see file "COPYING".
2
34c3a08a4a37 Copyright, etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 1
diff changeset
9 ###
34c3a08a4a37 Copyright, etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 1
diff changeset
10 ### Python 2.7 <= x < 3 required! Please refer to
34c3a08a4a37 Copyright, etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 1
diff changeset
11 ### README.txt for information on other depencies.
34c3a08a4a37 Copyright, etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 1
diff changeset
12 ###
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
13 import os
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
14 import sys
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
15 import signal
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
16 import re
45
035be8a9e982 Force reading of configuration in Unicode UTF-8.
Matti Hamalainen <ccr@tnsp.org>
parents: 44
diff changeset
17 import codecs
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
18 import math
73
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
19 import time
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
20 from subprocess import Popen, PIPE
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
21
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
22 import smtplib
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
23 from email.mime.text import MIMEText
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
24
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
25 import httplib2
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
26 import ConfigParser
20
1f0e79d1766e Cosmetic.
Matti Hamalainen <ccr@tnsp.org>
parents: 19
diff changeset
27
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
28 import oauth2client
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
29 from oauth2client import client
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
30 from oauth2client import tools
4
ad1e3184c8e3 Add missing import.
Matti Hamalainen <ccr@tnsp.org>
parents: 3
diff changeset
31 from oauth2client import file
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
32 from googleapiclient import discovery
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
33
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
34
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
35 ###
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
36 ### Misc. helper functions
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
37 ###
66
b08d159e35c7 Sanitize gcm_no_compare_fields[]
Matti Hamalainen <ccr@tnsp.org>
parents: 65
diff changeset
38 gcm_no_compare_fields = [
b08d159e35c7 Sanitize gcm_no_compare_fields[]
Matti Hamalainen <ccr@tnsp.org>
parents: 65
diff changeset
39 "id", "iCalUID", "etag", "sequence", "gcm_cal_id",
72
1ab40033bb87 Add 'creator' to event equality comparision excluded fields.
Matti Hamalainen <ccr@tnsp.org>
parents: 71
diff changeset
40 "created", "updated", "htmlLink", "organizer", "creator",
66
b08d159e35c7 Sanitize gcm_no_compare_fields[]
Matti Hamalainen <ccr@tnsp.org>
parents: 65
diff changeset
41 ]
b08d159e35c7 Sanitize gcm_no_compare_fields[]
Matti Hamalainen <ccr@tnsp.org>
parents: 65
diff changeset
42
76
a63cc3633adb Put log levels array into its own global variable.
Matti Hamalainen <ccr@tnsp.org>
parents: 75
diff changeset
43 gcm_log_levels = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
a63cc3633adb Put log levels array into its own global variable.
Matti Hamalainen <ccr@tnsp.org>
parents: 75
diff changeset
44
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
45
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
46 def gcm_get_log_level():
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
47 return gcm_log_levels.index(cfg.logging_level)
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
48
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
49
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
50 ## Wrapper for print() that does not break when redirecting stdin/out
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
51 ## because of piped output not having a defined encoding. We default
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
52 ## to UTF-8 encoding in output here.
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
53 def gcm_print(smsg):
47
a8fdecd4be61 Fixes to Unicode handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 46
diff changeset
54 gcm_msgbuf.append(smsg)
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
55 if sys.stdout.encoding != None:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
56 print(smsg.encode(sys.stdout.encoding))
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
57 else:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
58 print(smsg.encode("UTF-8"))
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
59
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
60
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
61 ## Fatal errors
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
62 def gcm_fatal(smsg):
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
63 gcm_print(u"ERROR: "+ smsg)
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
64 if cfg.email_ok and cfg.email != "off":
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
65 ## If e-mail is set, send e-mail
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
66 msg = MIMEText(("\n".join(gcm_msgbuf)).encode("UTF-8"), "plain")
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
67 msg.set_charset("UTF-8")
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
68 msg["Subject"] = cfg.email_subject
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
69 msg["From"] = cfg.email_sender
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
70 msg["To"] = ",".join(cfg.email_to)
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
71 gcm_print("Sending mail to {0} from {1}, subj: {2} ..".format(";".join(cfg.email_to), cfg.email_sender, cfg.email_subject))
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
72 try:
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
73 if cfg.email == "smtp":
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
74 gcm_print("Using SMTP server {0}, login {1}".format(cfg.email_smtp_server, cfg.email_smtp_user))
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
75 server = smtplib.SMTP(cfg.email_smtp_server)
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
76 if gcm_check_debug(4):
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
77 server.set_debuglevel(10)
95
b5cc76f18256 Fix e-mail sending and implement basic TLS support for outgoing SMTP.
Matti Hamalainen <ccr@tnsp.org>
parents: 93
diff changeset
78
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
79 if cfg.email_smtp_tls:
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
80 server.starttls()
95
b5cc76f18256 Fix e-mail sending and implement basic TLS support for outgoing SMTP.
Matti Hamalainen <ccr@tnsp.org>
parents: 93
diff changeset
81
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
82 server.login(cfg.email_smtp_user, cfg.email_smtp_password)
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
83 server.sendmail(cfg.email_sender, cfg.email_to, msg.as_string())
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
84 server.quit()
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
85 elif cfg.email == "sendmail":
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
86 gcm_print("Using sendmail {0}".format(cfg.email_sendmail))
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
87 p = Popen([cfg.email_sendmail, "-t", "-oi"], stdin=PIPE)
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
88 p.communicate(msg.as_string())
70
d5e3ca4b609d Improve error handling when e-mail sending fails.
Matti Hamalainen <ccr@tnsp.org>
parents: 68
diff changeset
89 except Exception as e:
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
90 gcm_print(u"FATAL: Oh noes, e-mail sending failed: {0}".format(str(e)))
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
91 sys.exit(1)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
92
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
93
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
94 ## Debug messages
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
95 def gcm_check_debug(level):
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
96 return cfg.debug and gcm_get_log_level() >= level
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
97
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
98 def gcm_debug(level, smsg):
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
99 if gcm_check_debug(level):
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
100 gcm_print(u"DBG: {0}".format(smsg))
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
101 else:
47
a8fdecd4be61 Fixes to Unicode handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 46
diff changeset
102 gcm_msgbuf.append(u"DBG: {0}".format(smsg))
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
103
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
104
24
1bce0c6a673c Comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 23
diff changeset
105 ## Handler for SIGINT signals
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
106 def gcm_signal_handler(signal, frame):
54
86d3a8eddbd7 Unicodeify.
Matti Hamalainen <ccr@tnsp.org>
parents: 53
diff changeset
107 gcm_print(u"\nQuitting due to SIGINT / Ctrl+C!")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
108 sys.exit(0)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
109
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
110
24
1bce0c6a673c Comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 23
diff changeset
111 ## Function for handling Google API credentials
99
4b84bb5bb8b5 Make credential_file and secret_file arguments to gcm_get_credentials().
Matti Hamalainen <ccr@tnsp.org>
parents: 98
diff changeset
112 def gcm_get_credentials(mcfg, credential_file, secret_file):
42
ac949d2b268a Add some error handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 41
diff changeset
113 try:
99
4b84bb5bb8b5 Make credential_file and secret_file arguments to gcm_get_credentials().
Matti Hamalainen <ccr@tnsp.org>
parents: 98
diff changeset
114 store = oauth2client.file.Storage(credential_file)
42
ac949d2b268a Add some error handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 41
diff changeset
115 except Exception as e:
99
4b84bb5bb8b5 Make credential_file and secret_file arguments to gcm_get_credentials().
Matti Hamalainen <ccr@tnsp.org>
parents: 98
diff changeset
116 gcm_fatal(u"Failed to read credential file:\n{0}\n\nERROR: {1}\n".format(credential_file, str(e)))
42
ac949d2b268a Add some error handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 41
diff changeset
117
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
118 credentials = store.get()
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
119 if not credentials or credentials.invalid:
42
ac949d2b268a Add some error handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 41
diff changeset
120 try:
99
4b84bb5bb8b5 Make credential_file and secret_file arguments to gcm_get_credentials().
Matti Hamalainen <ccr@tnsp.org>
parents: 98
diff changeset
121 flow = client.flow_from_clientsecrets(secret_file, mcfg.scope)
42
ac949d2b268a Add some error handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 41
diff changeset
122 except Exception as e:
99
4b84bb5bb8b5 Make credential_file and secret_file arguments to gcm_get_credentials().
Matti Hamalainen <ccr@tnsp.org>
parents: 98
diff changeset
123 gcm_fatal(u"Failed to fetch client secret:\n{0}\n\nERROR: {1}\n".format(secret_file, str(e)))
42
ac949d2b268a Add some error handling.
Matti Hamalainen <ccr@tnsp.org>
parents: 41
diff changeset
124
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
125 flow.user_agent = mcfg.app_name
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
126 credentials = tools.run_flow(flow, store, mcfg)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
127 if not credentials or credentials.invalid:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
128 gcm_fatal(u"Failed to authenticate / invalid credentials.")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
129 return credentials
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
130
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
131
103
fc361e368630 Improve gcm_dump_events() further by changing show parameter to a lambda
Matti Hamalainen <ccr@tnsp.org>
parents: 102
diff changeset
132 def gcm_dump_events(events, show):
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
133 for event in events:
103
fc361e368630 Improve gcm_dump_events() further by changing show parameter to a lambda
Matti Hamalainen <ccr@tnsp.org>
parents: 102
diff changeset
134 if show == None or show(event):
101
b5c381f9b51f Improve gcm_dump_events() to optionally show all events (deleted/cancelled).
Matti Hamalainen <ccr@tnsp.org>
parents: 100
diff changeset
135 ev_start = event["start"].get("dateTime", event["start"].get("date")) if "start" in event else "?"
b5c381f9b51f Improve gcm_dump_events() to optionally show all events (deleted/cancelled).
Matti Hamalainen <ccr@tnsp.org>
parents: 100
diff changeset
136 ev_end = event["end"].get("dateTime", event["end"].get("date")) if "end" in event else "?"
b5c381f9b51f Improve gcm_dump_events() to optionally show all events (deleted/cancelled).
Matti Hamalainen <ccr@tnsp.org>
parents: 100
diff changeset
137 summary = event["summary"] if "summary" in event else "?"
b5c381f9b51f Improve gcm_dump_events() to optionally show all events (deleted/cancelled).
Matti Hamalainen <ccr@tnsp.org>
parents: 100
diff changeset
138 status = "*" if event["status"] != u"cancelled" else "!"
104
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
139 gcm_print(u"[{0}] {1:25} - {2:25} : {3} [{4}] [{5}]".format(status, ev_start, ev_end, summary, event["iCalUID"], event["id"]))
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
140
56
597875ef885b Better debug prints.
Matti Hamalainen <ccr@tnsp.org>
parents: 55
diff changeset
141
597875ef885b Better debug prints.
Matti Hamalainen <ccr@tnsp.org>
parents: 55
diff changeset
142 ## Generate gcm IDs for given list of events
111
8b773358ad47 Use "id" field in source calendar events gcm_id generation, and "iCalUID" for the target calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 110
diff changeset
143 def gcm_generate_ids(events, calendar_id, sep, field):
26
1267d61f6224 Add function for generating unique internal IDs.
Matti Hamalainen <ccr@tnsp.org>
parents: 25
diff changeset
144 if not events:
1267d61f6224 Add function for generating unique internal IDs.
Matti Hamalainen <ccr@tnsp.org>
parents: 25
diff changeset
145 return events
1267d61f6224 Add function for generating unique internal IDs.
Matti Hamalainen <ccr@tnsp.org>
parents: 25
diff changeset
146
111
8b773358ad47 Use "id" field in source calendar events gcm_id generation, and "iCalUID" for the target calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 110
diff changeset
147 for event in events:
8b773358ad47 Use "id" field in source calendar events gcm_id generation, and "iCalUID" for the target calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 110
diff changeset
148 event["gcm_cal_id"] = calendar_id
8b773358ad47 Use "id" field in source calendar events gcm_id generation, and "iCalUID" for the target calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 110
diff changeset
149 event["gcm_id"] = calendar_id + sep + event[field]
26
1267d61f6224 Add function for generating unique internal IDs.
Matti Hamalainen <ccr@tnsp.org>
parents: 25
diff changeset
150
1267d61f6224 Add function for generating unique internal IDs.
Matti Hamalainen <ccr@tnsp.org>
parents: 25
diff changeset
151 return events
1267d61f6224 Add function for generating unique internal IDs.
Matti Hamalainen <ccr@tnsp.org>
parents: 25
diff changeset
152
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
153
53
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
154 ## Find event by its gcm_id from given list or return None if not found
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
155 def gcm_get_event_by_gcm_id(list, id):
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
156 for event in list:
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
157 if event["gcm_id"] == id:
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
158 return event
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
159 return None
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
160
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
161
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
162
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
163 def gcm_compare_events(ev1, ev2):
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
164 for field in ev1:
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
165 if not field in gcm_no_compare_fields and ev1[field] != ev2[field]:
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
166 return False
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
167 return True
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
168
63
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
169
110
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
170 ## Fetch events for given calendar
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
171 def gcm_fetch_events(calendarId, showDeleted):
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
172 events = []
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
173 ev_token = None
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
174 while True:
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
175 try:
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
176 result = service.events().list(
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
177 calendarId=calendarId,
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
178 showDeleted=showDeleted,
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
179 singleEvents=False,
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
180 pageToken=ev_token,
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
181 ).execute()
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
182 except Exception as e:
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
183 gcm_fatal(u"Failed to fetch calendar events for {0}:\n\nERROR: {1}\n".format(calendarId, str(e)))
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
184
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
185 events.extend(result.get("items", []))
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
186 ev_token = result.get("nextPageToken")
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
187 if not ev_token:
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
188 break
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
189
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
190 return events
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
191
c6771a596d77 Add gcm_fetch_events() function that properly implements chained event list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 109
diff changeset
192
67
c582522d2dcc Add a comment.
Matti Hamalainen <ccr@tnsp.org>
parents: 66
diff changeset
193 ###
c582522d2dcc Add a comment.
Matti Hamalainen <ccr@tnsp.org>
parents: 66
diff changeset
194 ### Class for parsing and manipulating RGB colors
c582522d2dcc Add a comment.
Matti Hamalainen <ccr@tnsp.org>
parents: 66
diff changeset
195 ###
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
196 class GCMColor():
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
197 def __init__(self, src = None):
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
198 if src == None:
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
199 self.r = self.g = self.b = 0
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
200 elif isinstance(src, basestring):
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
201 if len(src) == 6:
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
202 self.r = int(src[0:2], 16)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
203 self.g = int(src[2:4], 16)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
204 self.b = int(src[4:6], 16)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
205 elif len(src) == 7 and src[0] == "#":
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
206 self.r = int(src[1:3], 16)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
207 self.g = int(src[3:5], 16)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
208 self.b = int(src[6:7], 16)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
209 else:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
210 gcm_fatal(u"Expected hex-triplet string for GCMColor() initializer: {0}".format(src))
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
211 elif isinstance(src, GCMColor):
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
212 self.r = src.r
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
213 self.g = src.g
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
214 self.b = src.b
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
215 else:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
216 gcm_fatal(u"Invalid initializer for GCMColor() object.")
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
217
106
205767356d2c Add two helper functions to GCMColor class.
Matti Hamalainen <ccr@tnsp.org>
parents: 105
diff changeset
218 def to_hexrgb():
205767356d2c Add two helper functions to GCMColor class.
Matti Hamalainen <ccr@tnsp.org>
parents: 105
diff changeset
219 return "{0:02X}{1:02X}{2:02X}".format(self.r, self.g, self.b)
205767356d2c Add two helper functions to GCMColor class.
Matti Hamalainen <ccr@tnsp.org>
parents: 105
diff changeset
220
205767356d2c Add two helper functions to GCMColor class.
Matti Hamalainen <ccr@tnsp.org>
parents: 105
diff changeset
221 def to_hexrgb_lc():
205767356d2c Add two helper functions to GCMColor class.
Matti Hamalainen <ccr@tnsp.org>
parents: 105
diff changeset
222 return "{0:02x}{1:02x}{2:02x}".format(self.r, self.g, self.b)
205767356d2c Add two helper functions to GCMColor class.
Matti Hamalainen <ccr@tnsp.org>
parents: 105
diff changeset
223
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
224 def delta(self, other):
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
225 ctmp = GCMColor()
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
226 ctmp.r = other.r - self.r
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
227 ctmp.g = other.g - self.g
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
228 ctmp.b = other.b - self.b
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
229 return ctmp
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
230
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
231 def dist(self, other):
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
232 ctmp = self.delta(other)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
233 return math.sqrt(ctmp.r * ctmp.r + ctmp.g * ctmp.g + ctmp.b * ctmp.b)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
234
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
235
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
236 def gcm_find_nearest_color(colors, cfind, maxdist):
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
237 c_fg = GCMColor(cfind["foreground"])
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
238 c_bg = GCMColor(cfind["background"])
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
239
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
240 bdist_fg = 99999999999
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
241 bdist_bg = 99999999999
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
242 best_fit = None
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
243 for id, col in colors.iteritems():
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
244 dist_fg = GCMColor(col["foreground"]).dist(c_fg)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
245 dist_bg = GCMColor(col["background"]).dist(c_bg)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
246 if dist_fg <= bdist_fg and dist_bg <= bdist_bg:
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
247 best_fit = id
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
248 bdist_fg = dist_fg
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
249 bdist_bg = dist_bg
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
250
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
251 if bdist_fg <= maxdist and bdist_bg <= maxdist:
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
252 return best_fit
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
253 else:
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
254 return None
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
255
53
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
256
24
1bce0c6a673c Comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 23
diff changeset
257 ##
1bce0c6a673c Comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 23
diff changeset
258 ## Class for handling configuration / settings
1bce0c6a673c Comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 23
diff changeset
259 ##
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
260 class GCMSettings(dict):
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
261 def __init__(self):
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
262 self.m_data = {}
92
a348dfa6b132 Rename a variable/class member.
Matti Hamalainen <ccr@tnsp.org>
parents: 89
diff changeset
263 self.m_settable = {}
5
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
264 self.m_validate = {}
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
265 self.m_translate = {}
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
266
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
267 def __getattr__(self, name):
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
268 if name in self.m_data:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
269 return self.m_data[name]
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
270 else:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
271 gcm_fatal(u"GCMSettings.__getattr__(): No such attribute '"+ name +"'.")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
272
5
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
273 def mvalidate(self, name, value):
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
274 if name in self.m_validate and self.m_validate[name]:
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
275 if not self.m_validate[name](value):
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
276 gcm_fatal(u"GCMSettings.mvalidate(): Invalid value for attribute '{0}': {1}".format(name, value))
5
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
277
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
278 def mtranslate(self, name, value):
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
279 if name in self.m_translate and self.m_translate[name]:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
280 return self.m_translate[name](value)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
281 else:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
282 return value
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
283
92
a348dfa6b132 Rename a variable/class member.
Matti Hamalainen <ccr@tnsp.org>
parents: 89
diff changeset
284 def mdef(self, name, settable, validate, translate, value):
5
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
285 self.mvalidate(name, value)
92
a348dfa6b132 Rename a variable/class member.
Matti Hamalainen <ccr@tnsp.org>
parents: 89
diff changeset
286 self.m_settable[name] = settable
5
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
287 self.m_validate[name] = validate
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
288 self.m_translate[name] = translate
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
289 self.m_data[name] = self.mtranslate(name, value)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
290
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
291 def mset(self, name, value):
5
9d4152f32223 Add some code for settings validation.
Matti Hamalainen <ccr@tnsp.org>
parents: 4
diff changeset
292 self.mvalidate(name, value)
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
293 if name in self.m_data:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
294 self.m_data[name] = self.mtranslate(name, value)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
295 else:
43
a331209e24fc Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 42
diff changeset
296 gcm_fatal(u"GCMSettings.mset(): No such attribute '"+ name +"'.")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
297
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
298 def mget(self, name):
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
299 if name in self.m_data:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
300 return self.m_data[name]
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
301 else:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
302 return None
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
303
119
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
304 def mread(self, cfg_parser, sect):
92
a348dfa6b132 Rename a variable/class member.
Matti Hamalainen <ccr@tnsp.org>
parents: 89
diff changeset
305 for name in self.m_settable:
119
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
306 if cfg_parser.has_option(sect, name):
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
307 value = cfg_parser.get(sect, name)
6
ee6bf617f839 Implement configuration file reading.
Matti Hamalainen <ccr@tnsp.org>
parents: 5
diff changeset
308 self.mset(name, value)
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
309 gcm_debug(4, u"{0} -> '{1}' == {2}".format(name, value, self.mget(name)))
6
ee6bf617f839 Implement configuration file reading.
Matti Hamalainen <ccr@tnsp.org>
parents: 5
diff changeset
310
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
311 def is_str(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
312 return isinstance(mvalue, basestring)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
313
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
314 def is_string(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
315 return mvalue == None or self.is_str(mvalue)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
316
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
317 def is_log_level(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
318 if not self.is_str(mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
319 return False
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
320 else:
76
a63cc3633adb Put log levels array into its own global variable.
Matti Hamalainen <ccr@tnsp.org>
parents: 75
diff changeset
321 return mvalue.upper() in gcm_log_levels
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
322
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
323 def trans_log_level(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
324 return mvalue.upper()
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
325
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
326 def is_email_state(self, mvalue):
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
327 if not self.is_str(mvalue):
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
328 return False
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
329 else:
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
330 return mvalue.lower() in [u"off", u"sendmail", u"smtp"]
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
331
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
332 def trans_email_state(self, mvalue):
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
333 return mvalue.lower()
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
334
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
335 def is_filename(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
336 if not self.is_str(mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
337 return False
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
338 else:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
339 return re.match("^[a-z0-9][a-z0-9\.\_\-]+$", mvalue, flags=re.IGNORECASE)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
340
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
341 def trans_bool(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
342 if self.is_str(mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
343 if re.match("^\s*(true|1|on|yes)\s*$", mvalue, re.IGNORECASE):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
344 mvalue = True
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
345 elif re.match("^\s*(false|0|off|no)\s*$", mvalue, re.IGNORECASE):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
346 mvalue = False
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
347 else:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
348 return None
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
349 return mvalue
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
350
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
351 def is_bool(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
352 mval = self.trans_bool(mvalue)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
353 if not isinstance(mval, bool):
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
354 gcm_fatal(u"GCMSettings.is_bool(): Invalid boolean value '{0}', should be true|false|1|0|on|off|yes|no.".format(mvalue))
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
355 else:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
356 return True
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
357
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
358 def trans_list(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
359 morig = mvalue
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
360 if self.is_str(mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
361 mvalue = re.split("\s*,\s*", mvalue, flags=re.IGNORECASE)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
362 if not isinstance(mvalue, list):
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
363 gcm_fatal(u"GCMSettings.trans_list(): Could not parse list '{0}'.".format(mvalue))
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
364 elif not isinstance(mvalue, list):
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
365 gcm_fatal(u"GCMSettings.trans_list(): Invalid value '{0}'.".format(mvalue))
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
366 return mvalue
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
367
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
368 def is_list(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
369 return self.trans_list(mvalue)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
370
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
371 def is_email(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
372 if not self.is_string(mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
373 return False
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
374 else:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
375 return re.match("^.*?\s+<[a-z0-9]+[a-z0-9\.\+\-]*\@[a-z0-9]+[a-z0-9\.\-]+>\s*$|[a-z0-9]+[a-z0-9\.\+\-]*\@[a-z0-9]+[a-z0-9\.\-]+", mvalue, flags=re.IGNORECASE)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
376
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
377 def trans_email_list(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
378 if mvalue == None:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
379 return mvalue
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
380 else:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
381 return self.trans_list(mvalue.strip())
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
382
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
383 def is_email_list(self, mvalue):
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
384 mvalue = self.trans_email_list(mvalue)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
385 if mvalue != None:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
386 for email in mvalue:
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
387 if not self.is_email(email):
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
388 gcm_fatal(u"Invalid e-mail address '{0}' in list {1}.".format(email, ", ".join(mvalue)))
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
389 return True
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
390
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
391
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
392 ###
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
393 ### Main program starts
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
394 ###
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
395 gcm_msgbuf = []
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
396 signal.signal(signal.SIGINT, gcm_signal_handler)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
397
87
c3f8af496f46 Add "execution time elapsed" metering.
Matti Hamalainen <ccr@tnsp.org>
parents: 86
diff changeset
398 gcm_bench_start = time.time()
c3f8af496f46 Add "execution time elapsed" metering.
Matti Hamalainen <ccr@tnsp.org>
parents: 86
diff changeset
399
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
400
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
401 ## Settings
119
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
402 cfg_section = "gcm"
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
403 cfg = GCMSettings()
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
404
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
405 cfg.mdef("debug", True, cfg.is_bool, cfg.trans_bool, False)
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
406
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
407 cfg.mdef("email_ok", False, None, None, False)
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
408 cfg.mdef("email", True, cfg.is_email_state, cfg.trans_email_state, u"off")
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
409
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
410 cfg.mdef("email_to", True, cfg.is_email_list, cfg.trans_email_list, None)
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
411 cfg.mdef("email_sender", True, cfg.is_email, None, None)
49
cc30383f5f0d More Unicode fixes.
Matti Hamalainen <ccr@tnsp.org>
parents: 47
diff changeset
412 cfg.mdef("email_subject", True, cfg.is_string, None, u"Google Calendar MultiMerge status")
95
b5cc76f18256 Fix e-mail sending and implement basic TLS support for outgoing SMTP.
Matti Hamalainen <ccr@tnsp.org>
parents: 93
diff changeset
413
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
414 cfg.mdef("email_sendmail", True, cfg.is_string, None, "/usr/sbin/sendmail")
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
415 cfg.mdef("email_smtp_tls", True, cfg.is_bool, cfg.trans_bool, False)
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
416 cfg.mdef("email_smtp_server", True, cfg.is_string, None, None)
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
417 cfg.mdef("email_smtp_user", True, cfg.is_string, None, None)
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
418 cfg.mdef("email_smtp_password", True, cfg.is_string, None, None)
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
419
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
420 cfg.mdef("src_regex", True, cfg.is_string, None, u"^R:\s*(.*?)\s*\(\s*(.+?)\s*\)\s*$")
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
421 cfg.mdef("src_regmap", False, cfg.is_list, cfg.trans_list, [1, 2])
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
422 cfg.mdef("src_regmap_len", False, None, None, len(cfg.src_regmap))
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
423
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
424 cfg.mdef("dst_name", True, cfg.is_string, None, None)
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
425 cfg.mdef("dst_regex", True, cfg.is_string, None, None)
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
426 cfg.mdef("dst_id", True, cfg.is_string, None, None)
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
427
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
428 cfg.mdef("noauth_local_webserver", False, None, None, True)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
429 #cfg.mdef("auth_host_name", False, None, None, "localhost")
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
430 #cfg.mdef("auth_host_port", False, None, None, [8080, 8090])
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
431 cfg.mdef("logging_level", True, cfg.is_log_level, cfg.trans_log_level, "ERROR")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
432
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
433 # No need to touch these
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
434 cfg.mdef("app_name", False, None, None, "Google Calendar MultiMerge")
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
435 cfg.mdef("scope", False, None, None, "https://www.googleapis.com/auth/calendar")
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
436 #cfg.mdef("scope", False, None, None, "https://www.googleapis.com/auth/calendar.readonly")
23
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
437 cfg.mdef("secret_file", True, cfg.is_filename, None, "client_secret.json")
ff47f8088ef9 Make things more OO.
Matti Hamalainen <ccr@tnsp.org>
parents: 22
diff changeset
438 cfg.mdef("credential_file", True, cfg.is_filename, None, "client_credentials.json")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
439
6
ee6bf617f839 Implement configuration file reading.
Matti Hamalainen <ccr@tnsp.org>
parents: 5
diff changeset
440
89
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
441 ## Check arguments
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
442 if len(sys.argv) <= 1:
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
443 gcm_fatal(u"No configuration file specified.\nUsage: {0} <configfile>".format(sys.argv[0]))
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
444
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
445
6
ee6bf617f839 Implement configuration file reading.
Matti Hamalainen <ccr@tnsp.org>
parents: 5
diff changeset
446 ## Read, parse and validate configuration file
89
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
447 gcm_debug(3, u"Reading configuration from '{0}'.".format(sys.argv[1]))
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
448 try:
119
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
449 cfg_parser = ConfigParser.RawConfigParser()
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
450 cfg_parser.readfp(codecs.open(sys.argv[1], "r", "UTF-8"))
89
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
451 except Exception as e:
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
452 gcm_fatal(u"Failed to read configuration file '{0}': {1}".format(sys.argv[1], str(e)))
6
ee6bf617f839 Implement configuration file reading.
Matti Hamalainen <ccr@tnsp.org>
parents: 5
diff changeset
453
89
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
454 # Check that the required section exists
119
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
455 if not cfg_parser.has_section(cfg_section):
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
456 gcm_fatal(u"Invalid configuration, missing '{0}' section.".format(cfg_section))
7
f2ecfb3e04ee Check that the required section exists in configuration.
Matti Hamalainen <ccr@tnsp.org>
parents: 6
diff changeset
457
89
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
458 # Debug setting is a special case, we need to get it
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
459 # set before everything else, so do it here ..
119
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
460 if cfg_parser.has_option(cfg_section, "debug"):
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
461 cfg.mset("debug", cfg_parser.get(cfg_section, "debug"))
10
b237b96602ad We need to handle "debug" setting before other settings, so we need a
Matti Hamalainen <ccr@tnsp.org>
parents: 9
diff changeset
462
89
d68acec7cb99 Require configuration file.
Matti Hamalainen <ccr@tnsp.org>
parents: 88
diff changeset
463 # Parse the settings and validate
119
f671602635b7 Rename some objects and variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 114
diff changeset
464 cfg.mread(cfg_parser, cfg_section)
6
ee6bf617f839 Implement configuration file reading.
Matti Hamalainen <ccr@tnsp.org>
parents: 5
diff changeset
465
8
8367463fe94d Post-validate some settings.
Matti Hamalainen <ccr@tnsp.org>
parents: 7
diff changeset
466
8367463fe94d Post-validate some settings.
Matti Hamalainen <ccr@tnsp.org>
parents: 7
diff changeset
467 ## Validate settings
113
f45115bfb17a Implement sendmail mail sending support. Various e-mail related settings have also
Matti Hamalainen <ccr@tnsp.org>
parents: 111
diff changeset
468 if cfg.email != "off":
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
469 if cfg.email_subject == None or len(cfg.email_subject) == 0:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
470 gcm_fatal(u"E-mail enabled but email_subject not set.")
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
471 elif cfg.email_sender == None:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
472 gcm_fatal(u"E-mail enabled but email_sender not set.")
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
473 elif cfg.email_to == None:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
474 gcm_fatal(u"E-mail enabled but email_to not set.")
14
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
475 else:
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
476 cfg.mset("email_ok", True)
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
477
8262efacf3fb Initial implementation of sending e-mail in fatal error cases.
Matti Hamalainen <ccr@tnsp.org>
parents: 13
diff changeset
478
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
479 if len(cfg.src_regmap) != cfg.src_regmap_len:
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
480 gcm_fatal(u"Setting src_regmap list must be {0} items.".format(cfg.src_regmap_len))
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
481 else:
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
482 # Force to integers
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
483 try:
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
484 cfg.src_regmap = map(lambda x: int(x), cfg.src_regmap)
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
485 except Exception as e:
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
486 gcm_fatal(u"Invalid src_regmap: {0}".format(str(e)))
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
487
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
488
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
489 if not cfg.dst_regex and not cfg.dst_id:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
490 gcm_fatal(u"Target calendar ID or name required, but not set.")
8
8367463fe94d Post-validate some settings.
Matti Hamalainen <ccr@tnsp.org>
parents: 7
diff changeset
491
8367463fe94d Post-validate some settings.
Matti Hamalainen <ccr@tnsp.org>
parents: 7
diff changeset
492
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
493 ## Initialize and authorize API connection
99
4b84bb5bb8b5 Make credential_file and secret_file arguments to gcm_get_credentials().
Matti Hamalainen <ccr@tnsp.org>
parents: 98
diff changeset
494 credentials = gcm_get_credentials(cfg, cfg.credential_file, cfg.secret_file)
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
495 http = credentials.authorize(httplib2.Http())
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
496 service = discovery.build("calendar", "v3", http=http)
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
497
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
498
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
499 ## Fetch complete calendar list
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
500 gcm_debug(3, u"Fetching available calendars ..")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
501 calendars = []
19
095209b1ded3 Rename some variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 18
diff changeset
502 cal_token = None
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
503 while True:
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
504 # We want everything except deleted and hidden calendars
109
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
505 try:
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
506 result = service.calendarList().list(
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
507 showHidden=False,
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
508 showDeleted=False,
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
509 pageToken=cal_token
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
510 ).execute()
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
511 except Exception as e:
8cf20367a372 Add exception checking to calendar list fetching.
Matti Hamalainen <ccr@tnsp.org>
parents: 108
diff changeset
512 gcm_fatal(u"Failed to fetch calendar list:\n\nERROR: {0}\n".format(str(e)))
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
513
17
4168dde804ae Rename some variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 14
diff changeset
514 calendars.extend(result.get("items", []))
19
095209b1ded3 Rename some variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 18
diff changeset
515 cal_token = result.get("nextPageToken")
095209b1ded3 Rename some variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 18
diff changeset
516 if not cal_token:
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
517 break
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
518
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
519 if len(calendars) == 0:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
520 gcm_fatal(u"No calendars found?")
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
521
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
522 gcm_debug(3, u"{0} calendars total found.".format(len(calendars)))
50
f8618bae162a Improve debug messages and comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 49
diff changeset
523
1
74f172565752 Initial import.
Matti Hamalainen <ccr@tnsp.org>
parents:
diff changeset
524
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
525 ## Filter desired SOURCE calendars based on specified regexp
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
526 src_re = re.compile(cfg.src_regex, re.UNICODE)
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
527 dst_re = re.compile(cfg.dst_regex, re.UNICODE)
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
528 src_calendars = []
60
37705c4a35e1 Show target calendar information in debug mode.
Matti Hamalainen <ccr@tnsp.org>
parents: 59
diff changeset
529 dst_calendar = None
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
530 for calendar in calendars:
51
54644b29a9a3 Match also summaryOverride attribute against the source calendar regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 50
diff changeset
531 if u"summary" in calendar:
50
f8618bae162a Improve debug messages and comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 49
diff changeset
532 # Find destination calendar ID if not set
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
533 if not cfg.dst_id and dst_re.match(calendar["summary"]):
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
534 cfg.mset("dst_id", calendar["id"])
60
37705c4a35e1 Show target calendar information in debug mode.
Matti Hamalainen <ccr@tnsp.org>
parents: 59
diff changeset
535 dst_calendar = calendar
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
536 elif cfg.dst_id and calendar["id"] == cfg.dst_id:
86
d9e799a27ceb Make cfg.dest_id actually work.
Matti Hamalainen <ccr@tnsp.org>
parents: 85
diff changeset
537 dst_calendar = calendar
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
538
51
54644b29a9a3 Match also summaryOverride attribute against the source calendar regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 50
diff changeset
539 # If summary or summaryOverride match the regexp, add calendar
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
540 mre = src_re.match(calendar["summary"])
52
b87dbc887f63 Simplify.
Matti Hamalainen <ccr@tnsp.org>
parents: 51
diff changeset
541 if not mre and u"summaryOverride" in calendar:
114
591cc558bbcd Use summaryOverride field as summary for calendars where it is being matched
Matti Hamalainen <ccr@tnsp.org>
parents: 113
diff changeset
542 mre = src_re.match(calendar["summaryOverride"])
591cc558bbcd Use summaryOverride field as summary for calendars where it is being matched
Matti Hamalainen <ccr@tnsp.org>
parents: 113
diff changeset
543 calendar["summary"] = calendar["summaryOverride"]
52
b87dbc887f63 Simplify.
Matti Hamalainen <ccr@tnsp.org>
parents: 51
diff changeset
544
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
545 if mre:
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
546 calendar["gcm_title"] = mre.group(cfg.src_regmap[0])
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
547 calendar["gcm_id"] = mre.group(cfg.src_regmap[1])
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
548 src_calendars.append(calendar)
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
549
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
550 gcm_debug(3, u"{0} source calendars found.".format(len(src_calendars)))
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
551
50
f8618bae162a Improve debug messages and comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 49
diff changeset
552
f8618bae162a Improve debug messages and comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 49
diff changeset
553 ## Check if we have destination calendar ID
60
37705c4a35e1 Show target calendar information in debug mode.
Matti Hamalainen <ccr@tnsp.org>
parents: 59
diff changeset
554 if not dst_calendar:
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
555 gcm_fatal(u"Could not find target/destination calendar ID for '"+ cfg.dst_name +"'.")
60
37705c4a35e1 Show target calendar information in debug mode.
Matti Hamalainen <ccr@tnsp.org>
parents: 59
diff changeset
556 else:
93
46c1a3b6135a Cosmetic.
Matti Hamalainen <ccr@tnsp.org>
parents: 92
diff changeset
557 gcm_debug(3, u"Target calendar '{0}' [ ID: {1} ]".format(dst_calendar["summary"], dst_calendar["id"]))
9
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
558
01c933dba120 Filter source calendars based on regexp.
Matti Hamalainen <ccr@tnsp.org>
parents: 8
diff changeset
559
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
560 ## Fetch colors
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
561 try:
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
562 colors = service.colors().get().execute()
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
563 except Exception as e:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
564 gcm_fatal(u"Failed to fetch calendar color settings:\n\n{0}".format(str(e)))
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
565
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
566
11
fcdee7c04ed8 Implement fetching of source events.
Matti Hamalainen <ccr@tnsp.org>
parents: 10
diff changeset
567 ## Now, we fetch and collect events
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
568 gcm_debug(3, u"Fetching calendar events .. ")
19
095209b1ded3 Rename some variables.
Matti Hamalainen <ccr@tnsp.org>
parents: 18
diff changeset
569 src_events = []
11
fcdee7c04ed8 Implement fetching of source events.
Matti Hamalainen <ccr@tnsp.org>
parents: 10
diff changeset
570 for calendar in src_calendars:
97
524915af5e87 Cosmetics.
Matti Hamalainen <ccr@tnsp.org>
parents: 95
diff changeset
571 gcm_debug(4, u"- {0} ({1})".format(calendar["id"], calendar["summary"]))
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
572 c_found = None
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
573 if "colorId" in calendar and calendar["colorId"] in colors["calendar"]:
97
524915af5e87 Cosmetics.
Matti Hamalainen <ccr@tnsp.org>
parents: 95
diff changeset
574 gcm_debug(4, u" Calendar color: {0}".format(colors["calendar"][calendar["colorId"]]))
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
575 c_found = gcm_find_nearest_color(colors["event"], colors["calendar"][calendar["colorId"]], 100)
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
576 if c_found:
97
524915af5e87 Cosmetics.
Matti Hamalainen <ccr@tnsp.org>
parents: 95
diff changeset
577 gcm_debug(4, u" Found nearest event color ID: {0}, {1}".format(c_found, colors["event"][c_found]))
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
578 else:
97
524915af5e87 Cosmetics.
Matti Hamalainen <ccr@tnsp.org>
parents: 95
diff changeset
579 gcm_debug(4, u" No matching event color found!")
62
4891ed8d77d5 Implement nearest matching color search via cubic distance, and use it for
Matti Hamalainen <ccr@tnsp.org>
parents: 61
diff changeset
580
11
fcdee7c04ed8 Implement fetching of source events.
Matti Hamalainen <ccr@tnsp.org>
parents: 10
diff changeset
581 # Add events, if any, to main list
111
8b773358ad47 Use "id" field in source calendar events gcm_id generation, and "iCalUID" for the target calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 110
diff changeset
582 events = gcm_generate_ids(gcm_fetch_events(calendar["id"], False), calendar["id"], "___", "id")
11
fcdee7c04ed8 Implement fetching of source events.
Matti Hamalainen <ccr@tnsp.org>
parents: 10
diff changeset
583 if events:
31
6becdaa5c45f Set event colors (just sequentially now) based on which source calendar they belong to.
Matti Hamalainen <ccr@tnsp.org>
parents: 30
diff changeset
584 for event in events:
102
7ab6beb4c709 Only generate summaries and colors for non-deleted/cancelled events.
Matti Hamalainen <ccr@tnsp.org>
parents: 101
diff changeset
585 if event["status"] != u"cancelled":
7ab6beb4c709 Only generate summaries and colors for non-deleted/cancelled events.
Matti Hamalainen <ccr@tnsp.org>
parents: 101
diff changeset
586 if c_found != None:
7ab6beb4c709 Only generate summaries and colors for non-deleted/cancelled events.
Matti Hamalainen <ccr@tnsp.org>
parents: 101
diff changeset
587 event["colorId"] = c_found
7ab6beb4c709 Only generate summaries and colors for non-deleted/cancelled events.
Matti Hamalainen <ccr@tnsp.org>
parents: 101
diff changeset
588 event["summary"] = u"[{1}] {0}".format(event["summary"], calendar["gcm_id"])
21
f392d495c5b6 We need to extend a list, not append to it.
Matti Hamalainen <ccr@tnsp.org>
parents: 20
diff changeset
589 src_events.extend(events)
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
590 if gcm_check_debug(4):
103
fc361e368630 Improve gcm_dump_events() further by changing show parameter to a lambda
Matti Hamalainen <ccr@tnsp.org>
parents: 102
diff changeset
591 gcm_dump_events(events, (lambda ev: ev["status"] != u"cancelled"))
11
fcdee7c04ed8 Implement fetching of source events.
Matti Hamalainen <ccr@tnsp.org>
parents: 10
diff changeset
592
fcdee7c04ed8 Implement fetching of source events.
Matti Hamalainen <ccr@tnsp.org>
parents: 10
diff changeset
593
13
dd240a7ad913 Fetch current events in destination calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 11
diff changeset
594 ## Get current events
84
16edb168daa1 No need to display target calendar ID twice.
Matti Hamalainen <ccr@tnsp.org>
parents: 81
diff changeset
595 gcm_debug(3, u"Fetching current target calendar events.")
111
8b773358ad47 Use "id" field in source calendar events gcm_id generation, and "iCalUID" for the target calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 110
diff changeset
596 dst_events = gcm_generate_ids(gcm_fetch_events(cfg.dst_id, True), "", "", "iCalUID")
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
597 gcm_debug(3, u"Found {0} event(s).".format(len(dst_events)))
58
87fda54f935c Cleanup.
Matti Hamalainen <ccr@tnsp.org>
parents: 57
diff changeset
598
13
dd240a7ad913 Fetch current events in destination calendar.
Matti Hamalainen <ccr@tnsp.org>
parents: 11
diff changeset
599
27
824c3e5c6757 Work on event merging.
Matti Hamalainen <ccr@tnsp.org>
parents: 26
diff changeset
600 ## Start merging events ..
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
601 gcm_debug(3, u"Re-merging events to target calendar ..")
55
5b78f62b7de7 More work on merging stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 54
diff changeset
602 dst_ids = frozenset(map(lambda x: x["gcm_id"], dst_events))
5b78f62b7de7 More work on merging stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 54
diff changeset
603 src_ids = frozenset(map(lambda x: x["gcm_id"], src_events))
27
824c3e5c6757 Work on event merging.
Matti Hamalainen <ccr@tnsp.org>
parents: 26
diff changeset
604
81
ce02c0c00e64 Add debug information about how many events were new, updated or unchanged.
Matti Hamalainen <ccr@tnsp.org>
parents: 80
diff changeset
605 evn_new = evn_updated = evn_unchanged = 0
ce02c0c00e64 Add debug information about how many events were new, updated or unchanged.
Matti Hamalainen <ccr@tnsp.org>
parents: 80
diff changeset
606
27
824c3e5c6757 Work on event merging.
Matti Hamalainen <ccr@tnsp.org>
parents: 26
diff changeset
607 for event in src_events:
824c3e5c6757 Work on event merging.
Matti Hamalainen <ccr@tnsp.org>
parents: 26
diff changeset
608 # Does the event exist already in the target?
55
5b78f62b7de7 More work on merging stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 54
diff changeset
609 if event["gcm_id"] in dst_ids:
39
693db3f8cbe5 Begin importing event comparision stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 38
diff changeset
610 # Check if event NEEDS updating .. aka compare data
104
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
611 gcm_debug(4, u"Event {0} [{1}] exists, checking ..".format(event["id"], event["gcm_id"]))
53
ea62e0ed05ae Initial implementation of event comparision amd generally more clever about
Matti Hamalainen <ccr@tnsp.org>
parents: 52
diff changeset
612 d_event = gcm_get_event_by_gcm_id(dst_events, event["gcm_id"])
55
5b78f62b7de7 More work on merging stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 54
diff changeset
613 if not gcm_compare_events(event, d_event):
57
1c2cf6170219 Comments.
Matti Hamalainen <ccr@tnsp.org>
parents: 56
diff changeset
614 # Seems we need to update
104
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
615 gcm_debug(4, u"Updating event {0} [{1}]".format(event["id"], event["gcm_id"]))
39
693db3f8cbe5 Begin importing event comparision stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 38
diff changeset
616 try:
55
5b78f62b7de7 More work on merging stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 54
diff changeset
617 event.pop("sequence", None)
63
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
618 event.pop("id", None)
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
619 event["iCalUID"] = event["gcm_id"]
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
620 new_event = service.events().update(calendarId=cfg.dst_id, eventId=d_event["id"], body=event).execute()
105
481cfea49e19 Update counters only per successful operation.
Matti Hamalainen <ccr@tnsp.org>
parents: 104
diff changeset
621 evn_updated += 1
39
693db3f8cbe5 Begin importing event comparision stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 38
diff changeset
622 except Exception as e:
104
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
623 gcm_fatal(u"Failed to update event {0} [{1}]:\n\n{2}\n\nERROR: {3}\n".format(event["id"], event["gcm_id"], event, str(e)))
39
693db3f8cbe5 Begin importing event comparision stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 38
diff changeset
624 else:
81
ce02c0c00e64 Add debug information about how many events were new, updated or unchanged.
Matti Hamalainen <ccr@tnsp.org>
parents: 80
diff changeset
625 evn_unchanged += 1
104
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
626 gcm_debug(4, u"No need to update event {0} [{1}]".format(event["id"], event["gcm_id"]))
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
627 elif event["status"] != u"cancelled":
34
125c4cbca3ad Event merging work.
Matti Hamalainen <ccr@tnsp.org>
parents: 33
diff changeset
628 ## Event does not seem to exist. Insert new event.
104
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
629 gcm_debug(4, u"Inserting new event {0} [{1}]".format(event["id"], event["gcm_id"]))
63
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
630 event.pop("id", None)
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
631 event["iCalUID"] = event["gcm_id"] # Replace Google generated ID with our own
34
125c4cbca3ad Event merging work.
Matti Hamalainen <ccr@tnsp.org>
parents: 33
diff changeset
632 try:
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
633 new_event = service.events().insert(calendarId=cfg.dst_id, body=event).execute()
105
481cfea49e19 Update counters only per successful operation.
Matti Hamalainen <ccr@tnsp.org>
parents: 104
diff changeset
634 evn_new += 1
34
125c4cbca3ad Event merging work.
Matti Hamalainen <ccr@tnsp.org>
parents: 33
diff changeset
635 except Exception as e:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
636 gcm_fatal(u"Failed to insert new event:\n\n{0}\n\nERROR: {1}\n".format(event, str(e)))
63
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
637
81
ce02c0c00e64 Add debug information about how many events were new, updated or unchanged.
Matti Hamalainen <ccr@tnsp.org>
parents: 80
diff changeset
638 gcm_debug(3, "{0} new events, {1} updated, {2} unchanged.".format(evn_new, evn_updated, evn_unchanged))
ce02c0c00e64 Add debug information about how many events were new, updated or unchanged.
Matti Hamalainen <ccr@tnsp.org>
parents: 80
diff changeset
639
34
125c4cbca3ad Event merging work.
Matti Hamalainen <ccr@tnsp.org>
parents: 33
diff changeset
640
125c4cbca3ad Event merging work.
Matti Hamalainen <ccr@tnsp.org>
parents: 33
diff changeset
641 ## Remove "stale" events
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
642 gcm_debug(3, u"Purging stale events ..")
85
da09a3b1edaa Count and report number of purged events.
Matti Hamalainen <ccr@tnsp.org>
parents: 84
diff changeset
643 evn_purged = 0
38
54405de302d0 Attempt to delete stale events. Still needs a check for already deleted
Matti Hamalainen <ccr@tnsp.org>
parents: 37
diff changeset
644 for event in dst_events:
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
645 gcm_debug(4, u"Checking event {0}".format(event["gcm_id"]))
55
5b78f62b7de7 More work on merging stuff.
Matti Hamalainen <ccr@tnsp.org>
parents: 54
diff changeset
646 if not event["gcm_id"] in src_ids and event["status"] != u"cancelled":
104
f6274227114b Make debug/error messages more consistent.
Matti Hamalainen <ccr@tnsp.org>
parents: 103
diff changeset
647 gcm_debug(4, u"Deleting event {0} [{1}]".format(event["id"], event["gcm_id"]))
85
da09a3b1edaa Count and report number of purged events.
Matti Hamalainen <ccr@tnsp.org>
parents: 84
diff changeset
648 evn_purged += 1
63
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
649 try:
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
650 service.events().delete(calendarId=cfg.dst_id, eventId=event["id"]).execute()
63
6e38692e341f Fixes to event merging etc.
Matti Hamalainen <ccr@tnsp.org>
parents: 62
diff changeset
651 except Exception as e:
65
1eefa9b5e945 Unicodify.
Matti Hamalainen <ccr@tnsp.org>
parents: 64
diff changeset
652 gcm_fatal(u"Failed to delete stale event:\n{0}\n\nERROR: {1}\n".format(event, str(e)))
38
54405de302d0 Attempt to delete stale events. Still needs a check for already deleted
Matti Hamalainen <ccr@tnsp.org>
parents: 37
diff changeset
653
85
da09a3b1edaa Count and report number of purged events.
Matti Hamalainen <ccr@tnsp.org>
parents: 84
diff changeset
654 gcm_debug(3, "{0} events purged.".format(evn_purged))
da09a3b1edaa Count and report number of purged events.
Matti Hamalainen <ccr@tnsp.org>
parents: 84
diff changeset
655
da09a3b1edaa Count and report number of purged events.
Matti Hamalainen <ccr@tnsp.org>
parents: 84
diff changeset
656
75
ee05430f1a4d Update comment.
Matti Hamalainen <ccr@tnsp.org>
parents: 73
diff changeset
657 ##
ee05430f1a4d Update comment.
Matti Hamalainen <ccr@tnsp.org>
parents: 73
diff changeset
658 ## Finally, update the calendar name with timestamp
ee05430f1a4d Update comment.
Matti Hamalainen <ccr@tnsp.org>
parents: 73
diff changeset
659 ##
73
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
660 t_time = time.localtime()
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
661 t_str = time.strftime("%d.%m.%Y %H:%M", t_time)
77
e5e7b6e9bd44 Implement debug levels in the main code.
Matti Hamalainen <ccr@tnsp.org>
parents: 76
diff changeset
662 gcm_debug(3, u"Updating target calendar name timestamp {0}".format(t_str))
73
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
663
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
664 try:
98
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
665 dst_calendar["summary"] = cfg.dst_name.format(t_str)
fe3bfabf0b5f Rename settings dest_* and source_* to dst_* and src_* respectively.
Matti Hamalainen <ccr@tnsp.org>
parents: 97
diff changeset
666 new_calendar = service.calendars().update(calendarId=cfg.dst_id, body=dst_calendar).execute()
73
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
667 except Exception as e:
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
668 gcm_fatal(u"Failed to update target calendar:\n{0}\n\nERROR: {1}\n".format(dst_calendar, str(e)))
b3f8621f1a25 Change how the target calendar settings work a bit. Also implement display
Matti Hamalainen <ccr@tnsp.org>
parents: 72
diff changeset
669
27
824c3e5c6757 Work on event merging.
Matti Hamalainen <ccr@tnsp.org>
parents: 26
diff changeset
670
87
c3f8af496f46 Add "execution time elapsed" metering.
Matti Hamalainen <ccr@tnsp.org>
parents: 86
diff changeset
671 gcm_bench_end = time.time()
c3f8af496f46 Add "execution time elapsed" metering.
Matti Hamalainen <ccr@tnsp.org>
parents: 86
diff changeset
672 gcm_bench_elapsed = gcm_bench_end - gcm_bench_start
c3f8af496f46 Add "execution time elapsed" metering.
Matti Hamalainen <ccr@tnsp.org>
parents: 86
diff changeset
673
c3f8af496f46 Add "execution time elapsed" metering.
Matti Hamalainen <ccr@tnsp.org>
parents: 86
diff changeset
674 gcm_debug(3, u"Finished. {0} seconds elapsed.".format(gcm_bench_elapsed))