예제 #1
0
        private void checkForUpdate(String localVersion)
        {
            if (System.Diagnostics.Debugger.IsAttached && File.Exists(tzdbFilename))
            {
                return;
            }

            log.Debug("Checking for new timezone database...");
            String nodatimeURL = "http://nodatime.org/tzdb/latest.txt";
            String html        = "";

            System.Net.WebClient wc = new System.Net.WebClient();
            wc.Headers.Add("user-agent", Settings.Instance.Proxy.BrowserUserAgent);
            try {
                html = wc.DownloadString(nodatimeURL);
            } catch (System.Exception ex) {
                log.Error("Failed to get latest NodaTime db version.");
                OGCSexception.Analyse(ex);
                return;
            }

            if (string.IsNullOrEmpty(html))
            {
                log.Warn("Empty response from " + nodatimeURL);
            }
            else
            {
                html = html.TrimEnd('\r', '\n');
                if (html.EndsWith(localVersion + ".nzd"))
                {
                    log.Debug("Already have latest TZDB version.");
                }
                else
                {
                    Regex           rgx     = new Regex(@"https*:.*/tzdb(.*)\.nzd$", RegexOptions.IgnoreCase);
                    MatchCollection matches = rgx.Matches(html);
                    if (matches.Count > 0)
                    {
                        String remoteVersion = matches[0].Result("$1");
                        if (string.Compare(localVersion, remoteVersion, System.StringComparison.InvariantCultureIgnoreCase) < 0)
                        {
                            log.Debug("There is a new version " + remoteVersion);
                            try {
                                wc.DownloadFile(html, tzdbFilename);
                                log.Debug("New TZDB version downloaded - disposing of reference to old db data.");
                                instance = null;
                            } catch (System.Exception ex) {
                                log.Error("Failed to download new TZDB database from " + html);
                                OGCSexception.Analyse(ex);
                            }
                        }
                    }
                    else
                    {
                        log.Warn("Regex to extract latest version is no longer working!");
                    }
                }
            }
        }
        private DateTime WindowsTimeZone(EventDateTime time)
        {
            DateTime theDate = DateTime.Parse(time.DateTime ?? time.Date);

            if (time.TimeZone == null)
            {
                return(theDate);
            }

            LocalDateTime local     = new LocalDateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute);
            DateTimeZone  zone      = DateTimeZoneProviders.Tzdb[TimezoneDB.FixAlexa(time.TimeZone)];
            ZonedDateTime zonedTime = local.InZoneLeniently(zone);
            DateTime      zonedUTC  = zonedTime.ToDateTimeUtc();

            log.Fine("IANA Timezone \"" + time.TimeZone + "\" mapped to \"" + zone.Id.ToString() + "\" with a UTC of " + zonedUTC.ToString("dd/MM/yyyy HH:mm:ss"));
            return(zonedUTC);
        }
예제 #3
0
        private Microsoft.Office.Interop.Outlook.TimeZone WindowsTimeZone(string ianaZoneId)
        {
            ianaZoneId = TimezoneDB.FixAlexa(ianaZoneId);

            Microsoft.Office.Interop.Outlook.TimeZones tzs = oApp.TimeZones;
            var utcZones = new[] { "Etc/UTC", "Etc/UCT", "UTC", "Etc/GMT" };

            if (utcZones.Contains(ianaZoneId, StringComparer.OrdinalIgnoreCase))
            {
                log.Fine("Timezone \"" + ianaZoneId + "\" mapped to \"UTC\"");
                return(tzs["UTC"]);
            }

            NodaTime.TimeZones.TzdbDateTimeZoneSource tzDBsource = TimezoneDB.Instance.Source;

            // resolve any link, since the CLDR doesn't necessarily use canonical IDs
            var links = tzDBsource.CanonicalIdMap
                        .Where(x => x.Value.Equals(ianaZoneId, StringComparison.OrdinalIgnoreCase))
                        .Select(x => x.Key);

            // resolve canonical zones, and include original zone as well
            var possibleZones = tzDBsource.CanonicalIdMap.ContainsKey(ianaZoneId)
                ? links.Concat(new[] { tzDBsource.CanonicalIdMap[ianaZoneId], ianaZoneId })
                : links;

            // map the windows zone
            var mappings = tzDBsource.WindowsMapping.MapZones;
            var item     = mappings.FirstOrDefault(x => x.TzdbIds.Any(possibleZones.Contains));

            if (item == null)
            {
                throw new System.ApplicationException("Timezone \"" + ianaZoneId + "\" has no mapping.");
            }
            log.Fine("Timezone \"" + ianaZoneId + "\" mapped to \"" + item.WindowsId + "\"");

            return(tzs[item.WindowsId]);
        }
예제 #4
0
        private void buildOutlookPattern(Event ev, AppointmentItem ai, out RecurrencePattern oPattern)
        {
            if (ev.Recurrence == null)
            {
                oPattern = null; return;
            }

            Dictionary <String, String> ruleBook = explodeRrule(ev.Recurrence);

            if (ruleBook == null)
            {
                throw new ApplicationException("WARNING: The recurrence pattern is not compatible with Outlook. This event cannot be synced.");
            }
            log.Fine("Building Outlook recurrence pattern");
            oPattern = ai.GetRecurrencePattern();

            #region RECURRENCE PATTERN
            //RRULE:FREQ=WEEKLY;UNTIL=20150906T000000Z;BYDAY=SA

            switch (ruleBook["FREQ"])
            {
            case "DAILY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                break;
            }

            case "WEEKLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                // Need to work out dayMask from "BY" pattern
                // Eg "BYDAY=MO,TU,WE,TH,FR"
                OlDaysOfWeek dowMask = getDOWmask(ruleBook);
                if (dowMask != 0)
                {
                    oPattern.DayOfWeekMask = dowMask;
                }
                break;
            }

            case "MONTHLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance      = (gInstance == -1) ? 5 : gInstance;
                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (oPattern.DayOfWeekMask == (OlDaysOfWeek)127 && gInstance == -1 &&
                        (ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date)).Day > 28)
                    {
                        //In Outlook this is simply a monthly recurring
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                    }
                }
                if (ruleBook.ContainsKey("BYDAY"))
                {
                    if (ruleBook["BYDAY"].StartsWith("-1"))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = 5;
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart("-1".ToCharArray()));
                    }
                    else if ("1,2,3,4".Contains(ruleBook["BYDAY"].Substring(0, 1)))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = Convert.ToInt16(ruleBook["BYDAY"].Substring(0, 1));
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart(oPattern.Instance.ToString().ToCharArray()));
                    }
                }
                break;
            }

            case "YEARLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                //Google interval is years, Outlook is months
                if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1)
                {
                    oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]) * 12;
                }
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursYearNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance = (gInstance == -1) ? 5 : gInstance;

                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (ruleBook.ContainsKey("BYMONTH"))
                    {
                        oPattern.MonthOfYear = Convert.ToInt16(ruleBook["BYMONTH"]);
                    }
                }
                break;
            }
            }
            #endregion

            #region RANGE
            ai = OutlookOgcs.Calendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev);
            oPattern.PatternStartDate = ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date);
            if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1 && ruleBook["FREQ"] != "YEARLY")
            {
                oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]);
            }
            if (ruleBook.ContainsKey("COUNT"))
            {
                oPattern.Occurrences = Convert.ToInt16(ruleBook["COUNT"]);
            }
            if (ruleBook.ContainsKey("UNTIL"))
            {
                if (ruleBook["UNTIL"].StartsWith("4500"))
                {
                    log.Warn("Outlook can't handle end dates this far in the future. Converting to no end date.");
                    oPattern.NoEndDate = true;
                }
                else
                {
                    DateTime endDate;
                    if (ruleBook["UNTIL"].Length == 8 && !ruleBook["UNTIL"].EndsWith("Z"))
                    {
                        endDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture).Date;
                    }
                    else
                    {
                        endDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMddTHHmmssZ", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal);
                        endDate = endDate.AddHours(TimezoneDB.GetUtcOffset(ev.End.TimeZone)).Date;
                    }
                    if (endDate < oPattern.PatternStartDate)
                    {
                        log.Debug("PatternStartDate: " + oPattern.PatternStartDate.ToString("yyyyMMddHHmmss"));
                        log.Debug("PatternEndDate:   " + ruleBook["UNTIL"].ToString());
                        String summary = GoogleOgcs.Calendar.GetEventSummary(ev, onlyIfNotVerbose: true);
                        Forms.Main.Instance.Console.Update(summary + "The recurring Google event has an end date <i>before</i> the start date, which Outlook doesn't allow.<br/>" +
                                                           "The synced Outlook recurrence has been changed to a single occurrence.", Console.Markup.warning);
                        oPattern.Occurrences = 1;
                    }
                    else
                    {
                        oPattern.PatternEndDate = endDate;
                    }
                }
            }
            if (!ruleBook.ContainsKey("COUNT") && !ruleBook.ContainsKey("UNTIL"))
            {
                oPattern.NoEndDate = true;
            }
            #endregion
        }