Mercurial > hg > gcmultimerge
comparison multimerge.py @ 62:4891ed8d77d5
Implement nearest matching color search via cubic distance, and use it for
finding best matching color from available event colors based on source
calendar color.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 11 Jul 2016 13:37:26 +0300 |
parents | 9fe4faa80687 |
children | 6e38692e341f |
comparison
equal
deleted
inserted
replaced
61:9fe4faa80687 | 62:4891ed8d77d5 |
---|---|
10 import os | 10 import os |
11 import sys | 11 import sys |
12 import signal | 12 import signal |
13 import re | 13 import re |
14 import codecs | 14 import codecs |
15 import math | |
15 #import time | 16 #import time |
16 #import datetime | 17 #import datetime |
17 | 18 |
18 import smtplib | 19 import smtplib |
19 from email.mime.text import MIMEText | 20 from email.mime.text import MIMEText |
130 for field in ev1: | 131 for field in ev1: |
131 if not field in gcm_no_compare_fields and ev1[field] != ev2[field]: | 132 if not field in gcm_no_compare_fields and ev1[field] != ev2[field]: |
132 return False | 133 return False |
133 return True | 134 return True |
134 | 135 |
136 class GCMColor(): | |
137 def __init__(self, src = None): | |
138 if src == None: | |
139 self.r = self.g = self.b = 0 | |
140 elif isinstance(src, basestring): | |
141 if len(src) == 6: | |
142 self.r = int(src[0:2], 16) | |
143 self.g = int(src[2:4], 16) | |
144 self.b = int(src[4:6], 16) | |
145 elif len(src) == 7 and src[0] == "#": | |
146 self.r = int(src[1:3], 16) | |
147 self.g = int(src[3:5], 16) | |
148 self.b = int(src[6:7], 16) | |
149 else: | |
150 gcm_fatal("Expected hex-triplet string for GCMColor() initializer: {0}".format(src)) | |
151 elif isinstance(src, GCMColor): | |
152 self.r = src.r | |
153 self.g = src.g | |
154 self.b = src.b | |
155 else: | |
156 gcm_fatal("Invalid initializer for GCMColor() object.") | |
157 | |
158 def delta(self, other): | |
159 ctmp = GCMColor() | |
160 ctmp.r = other.r - self.r | |
161 ctmp.g = other.g - self.g | |
162 ctmp.b = other.b - self.b | |
163 return ctmp | |
164 | |
165 def dist(self, other): | |
166 ctmp = self.delta(other) | |
167 return math.sqrt(ctmp.r * ctmp.r + ctmp.g * ctmp.g + ctmp.b * ctmp.b) | |
168 | |
169 | |
170 def gcm_find_nearest_color(colors, cfind, maxdist): | |
171 c_fg = GCMColor(cfind["foreground"]) | |
172 c_bg = GCMColor(cfind["background"]) | |
173 | |
174 bdist_fg = 99999999999 | |
175 bdist_bg = 99999999999 | |
176 best_fit = None | |
177 for id, col in colors.iteritems(): | |
178 dist_fg = GCMColor(col["foreground"]).dist(c_fg) | |
179 dist_bg = GCMColor(col["background"]).dist(c_bg) | |
180 if dist_fg <= bdist_fg and dist_bg <= bdist_bg: | |
181 best_fit = id | |
182 bdist_fg = dist_fg | |
183 bdist_bg = dist_bg | |
184 | |
185 if bdist_fg <= maxdist and bdist_bg <= maxdist: | |
186 return best_fit | |
187 else: | |
188 return None | |
189 | |
135 | 190 |
136 ## | 191 ## |
137 ## Class for handling configuration / settings | 192 ## Class for handling configuration / settings |
138 ## | 193 ## |
139 class GCMSettings(dict): | 194 class GCMSettings(dict): |
406 ## Check if we have destination calendar ID | 461 ## Check if we have destination calendar ID |
407 if not dst_calendar: | 462 if not dst_calendar: |
408 gcm_fatal(u"Could not find target/destination calendar ID for '"+ cfg.dest_name +"'.") | 463 gcm_fatal(u"Could not find target/destination calendar ID for '"+ cfg.dest_name +"'.") |
409 else: | 464 else: |
410 gcm_debug(u"Target calendar '{0}' id {1}.".format(dst_calendar["summary"], dst_calendar["id"])) | 465 gcm_debug(u"Target calendar '{0}' id {1}.".format(dst_calendar["summary"], dst_calendar["id"])) |
466 | |
467 | |
468 ## Fetch colors | |
469 try: | |
470 colors = service.colors().get().execute() | |
471 except Exception as e: | |
472 gcm_fatal("Failed to fetch calendar color settings:\n\n{0}".format(str(e))) | |
411 | 473 |
412 | 474 |
413 ## Now, we fetch and collect events | 475 ## Now, we fetch and collect events |
414 gcm_debug(u"Fetching calendar events .. ") | 476 gcm_debug(u"Fetching calendar events .. ") |
415 src_events = [] | 477 src_events = [] |
421 singleEvents=True, | 483 singleEvents=True, |
422 showDeleted=False, | 484 showDeleted=False, |
423 # orderBy="startTime", | 485 # orderBy="startTime", |
424 ).execute() | 486 ).execute() |
425 | 487 |
488 c_found = None | |
489 if "colorId" in calendar and calendar["colorId"] in colors["calendar"]: | |
490 gcm_debug("Calendar color: {0}".format(colors["calendar"][calendar["colorId"]])) | |
491 c_found = gcm_find_nearest_color(colors["event"], colors["calendar"][calendar["colorId"]], 100) | |
492 if c_found: | |
493 gcm_debug("Found nearest event color ID: {0}, {1}".format(c_found, colors["event"][c_found])) | |
494 else: | |
495 gcm_debug("No matching event color found!") | |
496 | |
426 # Add events, if any, to main list | 497 # Add events, if any, to main list |
427 events = gcm_generate_ids(result.get("items", []), calendar["id"]) | 498 events = gcm_generate_ids(result.get("items", []), calendar["id"]) |
428 if events: | 499 if events: |
429 for event in events: | 500 for event in events: |
430 if "colorId" in calendar: | 501 if c_found != None: |
431 event["colorId"] = calendar["colorId"] | 502 event["colorId"] = c_found |
432 event["summary"] = u"[{1}] {0}".format(event["summary"], calendar["gcm_id"]) | 503 event["summary"] = u"[{1}] {0}".format(event["summary"], calendar["gcm_id"]) |
433 src_events.extend(events) | 504 src_events.extend(events) |
434 if cfg.debug: | 505 if cfg.debug: |
435 gcm_dump_events(events) | 506 gcm_dump_events(events) |
436 | 507 |