def contact_position(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) curnode = transform_ctx.current() s=xml2util.GetNodeValue(curnode) # Extract the types types = [] for child in curnode.children: if child.name == "Type": types.append(xml2util.GetNodeValue(child).upper()) types.sort() position = 1 prevnode = curnode.prev while prevnode != None: if prevnode.name == curnode.name: #print "found another", curnode.name # Now compare types prev_types = [] for child in prevnode.children: if child.name == "Type": prev_types.append(xml2util.GetNodeValue(child).upper()) prev_types.sort() #print "prev types:",prev_types if prev_types == types: position += 1 prevnode = prevnode.prev return position
def ConvertASTimezoneToVcal(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() dst_node = transform_ctx.insertNode() s=xml2util.GetNodeValue(transform_ctx.current()) if len(s) > 0: dcas = base64.b64decode(s) base_node = transform_ctx.insertNode() astd = ASTimezoneData() astd.UnpackFromAirsync(dcas) astd.dump() sdate = FindASDateElementContent(src_node.parent,"StartTime") if sdate ==None: sdate=datetime.datetime.now() year = sdate.year else: year = int(sdate[0:4]) astd.ToVcalTZ(dst_node,year) CUR_TZ["current"] = astd.tzcurrent # We now have a (hopefully valid) timezone entry as the current # timezone. We need to back-convert the timezoneable dates as # they appear. return ""
def task_due_date_from_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() asdate = tzutils.TaskTextToDate(xml2util.GetNodeValue(transform_ctx.current())) if tzconv.curtz() != None: # if we have a tz, we must insert the ID and convert to it dst_node.newChild(None,"TimezoneID",tzconv.curtz().name) asdate = tzconv.ConvertToLocal(asdate,tzconv.curtz()) result = asdate.strftime(DATE_FORMAT_VCALTASKLOCAL) else: # if not, does the source have a UtcStartDate element? nd = xml2util.FindChildNode(src_node.parent,"UtcDueDate") if nd != None: result = tzutils.TaskTextToDate(xml2util.GetNodeValue(nd)).strftime(DATE_FORMAT_VCALTASK) else: # we don't have this either. Better hope that the DueDate value # is correct. result = asdate.strftime(DATE_FORMAT_VCALTASKLOCAL) dst_node = transform_ctx.insertNode() dst_node.newChild(None,"Content",result) return ""
def event_datetime_from_airsync(ctx, node=None): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) if node: node = libxml2.xmlNode(_obj=node[0]) else: node = transform_ctx.current() return tzutils.TextToDate(xml2util.GetNodeValue(node)).strftime(DATE_FORMAT_EVENT)
def TZFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) tznode = transform_ctx.current() tzdata = base64.b64decode(xml2util.GetNodeValue(tznode)) # Some AS timezones fail to include a year. See if we can # graft this from the AS body datenode = xml2util.FindChildNode(tznode.parent,"StartTime") if datenode == None: datenode = xml2util.FindChildNode(tznode.parent,"DtStamp") if datenode == None: year = datetime.datetime.now().year else: txtyear = xml2util.GetNodeValue(datenode) year = int(txtyear[0:4]) tz = tzdatabase.TZFromAirsync(tzdata,year) # only add it if we have a valid timezone if tz!=None: tzdatabase.tzdb.PutTimezone(tz) return ""
def event_reminder_to_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() content_node = xml2util.FindChildNode(src_node, "Content") value_node = xml2util.FindChildNode(src_node, "Value") related_node = xml2util.FindChildNode(src_node, "Related") if value_node == None or xml2util.GetNodeValue(value_node).lower() != "duration": return "" if related_node != None and xml2util.GetNodeValue(related_node).lower() != "start": return "" s = xml2util.GetNodeValue(content_node) s = s.lstrip("-PT") s = s.upper() days=0 hours=0 minutes=0 if s.rfind("D") != -1: days = int(s[:s.rfind("D")]) s = s[s.rfind("D")+1:] if s.rfind("H") != -1: hours = int(s[:s.rfind("H")]) s = s[s.rfind("H")+1:] if s.rfind("M") != -1: minutes = int(s[:s.rfind("M")]) s = s[s.rfind("M")+1:] return str(days * MINUTES_PER_DAY + hours * MINUTES_PER_HOUR + minutes)
def ExceptionDateTimeFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() dst_node = transform_ctx.insertNode() exception_deleted = xml2util.GetNodeValue( xml2util.FindChildNode(src_node, "Deleted")) exception_date = xml2util.GetNodeValue( xml2util.FindChildNode(src_node, "ExceptionStartTime")) if exception_deleted != "1": raise ValueError( "Opensync does not support exceptions for modified occurrences") # We need to convert to current timezone if one is provided, else # we can assume UTC date = dateutil.TextToDate(exception_date) curtz = tzdatabase.tzdb.GetCurrentTimezone() if curtz != None: date = date.astimezone(curtz) dst_node.setProp("TimezoneID", curtz.name) dst_node = transform_ctx.insertNode() dst_node.setProp("Value", "DATE") tznode = dst_node.newChild(None, "Content", date.strftime(DATE_FORMAT_SHORT)) return ""
def task_due_date_to_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) localDate,utcDate = tzconv.ConvertDateNodeToUTC(transform_ctx.current()) dst_node = transform_ctx.insertNode() tasks_ns = dst_node.searchNsByHref(transform_ctx.outputDoc(), "http://synce.org/formats/airsync_wm5/tasks") n=dst_node.newChild(tasks_ns,"DueDate",localDate.strftime(DATE_FORMAT_TASKLOCAL)) n=dst_node.newChild(tasks_ns,"UtcDueDate",utcDate.strftime(DATE_FORMAT_TASK)) return ""
def HandleOSTZRRule(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) tznode = transform_ctx.current() tzdatabase.NewTZRRuleFromXML(tznode,tzdatabase.tzdb) return ""
def TimeTransparencyFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) if xml2util.GetNodeValue(transform_ctx.current()) == "0": return "TRANSPARENT" else: return "OPAQUE" # 'Busy' is our default value
def event_reminder_from_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) s = int(xml2util.GetNodeValue(transform_ctx.current())) if s % MINUTES_PER_DAY == 0: return "-P%iD" % (s / MINUTES_PER_DAY) elif s % MINUTES_PER_HOUR == 0: return "-PT%iH" % (s / MINUTES_PER_HOUR) else: return "-PT%iM" % s
def AllTZToOpensync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) dst_node = transform_ctx.insertNode() tzs = tzdatabase.tzdb.GetTimezoneList() for tz in tzs: tzdatabase.TZToXML(dst_node,tzdatabase.tzdb.GetTimezone(tz)) return ""
def event_recurrence_from_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() dst_node = transform_ctx.insertNode() interval_node = xml2util.FindChildNode(src_node, "Interval") until_node = xml2util.FindChildNode(src_node, "Until") occurrences_node = xml2util.FindChildNode(src_node, "Occurrences") type_node = xml2util.FindChildNode(src_node, "Type") dayofweek_node = xml2util.FindChildNode(src_node, "DayOfWeek") dayofmonth_node = xml2util.FindChildNode(src_node, "DayOfMonth") weekofmonth_node = xml2util.FindChildNode(src_node, "WeekOfMonth") monthofyear_node = xml2util.FindChildNode(src_node, "MonthOfYear") # Add the common nodes that don't really require conversion if interval_node != None: dst_node.newChild(None, "Rule", "INTERVAL=%s" % xml2util.GetNodeValue(interval_node)) if until_node != None: dst_node.newChild(None, "Rule", "UNTIL=%s" % xml2util.GetNodeValue(until_node)) if occurrences_node != None: dst_node.newChild(None, "Rule", "COUNT=%s" % xml2util.GetNodeValue(occurrences_node)) if type_node != None: type = int(xml2util.GetNodeValue(type_node)) # Special case: we can treat this as simple weekly event if type == 0 and dayofweek_node != None: type = 1 if type == 0: dst_node.newChild(None, "Rule", "FREQ=DAILY") elif type == 1: dst_node.newChild(None, "Rule", "FREQ=WEEKLY") dst_node.newChild(None, "Rule", "BYDAY=%s" % airsync_days_to_vcal_days(xml2util.GetNodeValue(dayofweek_node))) elif type == 2: dst_node.newChild(None, "Rule", "FREQ=MONTHLY") dst_node.newChild(None, "Rule", "BYMONTHDAY=%s" % xml2util.GetNodeValue(dayofmonth_node)) elif type == 3: dst_node.newChild(None, "Rule", "FREQ=MONTHLY") dst_node.newChild(None, "Rule", "BYDAY=%s" % generate_vcal_byday(xml2util.GetNodeValue(weekofmonth_node), xml2util.GetNodeValue(dayofweek_node))) elif type == 5: dst_node.newChild(None, "Rule", "FREQ=YEARLY") dst_node.newChild(None, "Rule", "BYMONTH=%s" % xml2util.GetNodeValue(monthofyear_node)) dst_node.newChild(None, "Rule", "BYMONTHDAY=%s" % xml2util.GetNodeValue(dayofmonth_node)) elif type == 6: dst_node.newChild(None, "Rule", "FREQ=YEARLY") dst_node.newChild(None, "Rule", "BYMONTH=%s" % xml2util.GetNodeValue(monthofyear_node)) dst_node.newChild(None, "Rule", "BYDAY=%s" % generate_vcal_byday(xml2util.GetNodeValue(weekofmonth_node), xml2util.GetNodeValue(dayofweek_node))) else: # Unsupported type raise ValueError("Unknown recurrence type %d from Airsync" % type) else: # If we don't know what type of recurrence it is, we # can't construct its vcal rules raise ValueError("No recurrence type specified from Airsync") return ""
def contact_has_type(ctx, type_string): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) curnode = transform_ctx.current() s=xml2util.GetNodeValue(curnode) for child in curnode.children: if child.name != "Type": continue if xml2util.GetNodeValue(child).upper() == type_string: return True return False
def AllDayEventToAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() datetext = xml2util.GetNodeValue( xml2util.FindChildNode(src_node, "Content")) if datetext.find("T") >= 0: return "0" else: return "1"
def AttendeeFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() dst_node = transform_ctx.insertNode() email = xml2util.GetNodeValue(xml2util.FindChildNode(src_node, "Email")) name = xml2util.GetNodeValue(xml2util.FindChildNode(src_node, "Name")) if email != "": dst_node.newChild(None, "Content", "MAILTO:%s" % email) dst_node.newChild(None, "CommonName", name) return ""
def DateToAirsyncLocal(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) dst_node = transform_ctx.insertNode() tznode = transform_ctx.current() # handle input (could be DATE or DATE-TIME) date = dateutil.XMLDateTimeToDate(tznode, tzdatabase.tzdb) return date.strftime(DATE_FORMAT_TASK) + "Z"
def ExtractTZData(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) tznode = transform_ctx.current() timezone = tzutils.tzone.TZInfoFromVcal(tznode) TZDB[timezone.name]=timezone astd = ASTimezoneData() astd.FromVcalTZ(timezone) astd.dump() return base64.b64encode(astd.PackToAirsync())
def all_description_from_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() s=xml2util.GetNodeValue(transform_ctx.current()) asnote = "" if len(s) > 0: dc = base64.b64decode(s) try: asnote = pyrtfcomp.RTFConvertToUTF8(dc,1) except pyrtfcomp.RTFException, ConvErr: pass
def ClassFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) s = xml2util.GetNodeValue(transform_ctx.current()) if s == "2": return "PRIVATE" elif s == "3": return "CONFIDENTIAL" else: return "PUBLIC" # 'PUBLIC' is our default value
def StatusFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() s = xml2util.GetNodeValue(transform_ctx.current()) if s == "1": base_node = transform_ctx.insertNode() stat_node = base_node.newChild(None, "Status", None) stat_node.newChild(None, "Content", "COMPLETED") pcnt_node = base_node.newChild(None, "PercentComplete", None) pcnt_node.newChild(None, "Content", "100") return ""
def all_description_to_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() content_node = xml2util.FindChildNode(src_node, "Content") s = xml2util.GetNodeValue(content_node) ec = "" if len(s) > 0: try: asnote = pyrtfcomp.RTFConvertFromUTF8(s,RTFHDR,1) ec=base64.b64encode(asnote) except pyrtfcomp.RTFException, ConvErr: pass
def task_start_date_to_airsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) # StartDate without DueDate is not allowed duedate_node = xml2util.FindChildNode(transform_ctx.current().parent, "DateDue") if not duedate_node: return "" localDate,utcDate = tzconv.ConvertDateNodeToUTC(transform_ctx.current()) dst_node = transform_ctx.insertNode() tasks_ns = dst_node.searchNsByHref(transform_ctx.outputDoc(), "http://synce.org/formats/airsync_wm5/tasks") n=dst_node.newChild(tasks_ns,"StartDate",localDate.strftime(DATE_FORMAT_TASKLOCAL)) n=dst_node.newChild(tasks_ns,"UtcStartDate",utcDate.strftime(DATE_FORMAT_TASK)) return ""
def CurrentTZToAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) tznode = transform_ctx.current() tz = tzdatabase.tzdb.GetCurrentTimezone() if tz!=None: dst_node = transform_ctx.insertNode() tznode=dst_node.newChild(None,"Timezone",base64.b64encode(tzdatabase.TZToAirsync(tz))) ns=tznode.newNs("http://synce.org/formats/airsync_wm5/calendar",None) tznode.setNs(ns) return ""
def OSDateToAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) tznode = transform_ctx.current() # handle input (could be DATE or DATE-TIME) date = dateutil.XMLDateTimeToDate(tznode,tzdatabase.tzdb) # convert date to UTC utcdate = date.astimezone(tzutils.tzone.utc) return utcdate.strftime(DATE_FORMAT_EVENT)
def AlarmFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() s = int(xml2util.GetNodeValue(src_node)) if s % MINUTES_PER_DAY == 0: return "-P%iD" % (s / MINUTES_PER_DAY) elif s % MINUTES_PER_HOUR == 0: return "-PT%iH" % (s / MINUTES_PER_HOUR) else: return "-PT%iM" % s
def PriorityFromAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) s = xml2util.GetNodeValue(transform_ctx.current()) if s == "0": return "7" elif s == "1": return "5" elif s == "2": return "3" else: return "0" # We can use the unspecced one here if we get such an one from Airsync
def OSTextToAirsyncRTF(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() s=xml2util.GetNodeValue(transform_ctx.current()) ec = "" if len(s) > 0: try: asnote = pyrtfcomp.RTFConvertFromUTF8(s,RTFHDR,1) ec=base64.b64encode(asnote) except pyrtfcomp.RTFException, ConvErr: pass
def AttendeeToAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) src_node = transform_ctx.current() dst_node = transform_ctx.insertNode() email = xml2util.GetNodeValue(xml2util.FindChildNode(src_node, "Content"))[7:] name = xml2util.GetNodeValue(xml2util.FindChildNode( src_node, "CommonName")) if name != "": dst_node.newChild(None, "Name", name) dst_node.newChild(None, "Email", email) return ""
def StatusToAirsync(ctx): parser_ctx, transform_ctx = xml2util.ExtractContexts(ctx) curnode = transform_ctx.current() s = xml2util.GetNodeValue(curnode) if s == "COMPLETED": return "1" else: # check that PercentComplete == 100% - mark it completed if # this is the case. up = xml2util.FindChildNode(curnode.parent.parent, "PercentComplete") if up != None: ct = xml2util.FindChildNode(up, "Content") if ct != None: if xml2util.GetNodeValue(ct) == "100": return "1" return "0"