Esempio n. 1
0
        private void AppendFreeBusyEntry(
            DateTime startUtc,
            DateTime endUtc,
            string subject,
            string location,
            string organizer,
            BusyStatus busyStatus,
            StringBuilder result)
        {
            DateTime startLocal = OlsonUtil.ConvertFromUTC(startUtc, Request.TimeZone);
            DateTime endLocal   = OlsonUtil.ConvertFromUTC(endUtc, Request.TimeZone);
            int      status     = ConversionsUtil.ConvertBusyStatusToGoogleResponse(busyStatus);

            ConversionsUtil.EscapeNonAlphaNumeric(subject, escapedSubject);
            ConversionsUtil.EscapeNonAlphaNumeric(location, escapedLocation);
            ConversionsUtil.EscapeNonAlphaNumeric(organizer, escapedOrganizer);

            result.AppendFormat("['{0}','{1}','{2}','{3}','{4}',{5}]",
                                escapedSubject,
                                DateUtil.FormatDateTimeForGoogle(startLocal),
                                DateUtil.FormatDateTimeForGoogle(endLocal),
                                escapedLocation,
                                escapedOrganizer,
                                status);
        }
Esempio n. 2
0
        /// <summary>
        /// Parses the incoming Exchange request from GCal. The requests are of the form:
        /// [ version #, ID, [list of emails], startdate/enddate, sincedata, timezone]
        /// /// </summary>
        /// <param name="rawInput">The incoming GCal request string</param>
        private void Parse(string rawInput)
        {
            if (rawInput != null)
            {
                rawInput = rawInput.Trim();
            }

            /* Test that the request is not null or empty */
            if (string.IsNullOrEmpty(rawInput))
            {
                throw new GCalExchangeException(GCalExchangeErrorCode.MalformedRequest,
                                                "GCalRequest is null or empty.");
            }

            log.InfoFormat("Request received from GCal. [body={0}]", rawInput);

            /* Test that the request has starting and ending brackets */
            if (!rawInput.StartsWith("[") || !rawInput.EndsWith("]"))
            {
                throw new GCalExchangeException(GCalExchangeErrorCode.MalformedRequest,
                                                String.Format("GCalRequest does start and end in brackets: [rawInput:{0}]", rawInput));
            }

            /* Remove the start and end brackets */
            string requestContent = rawInput.Remove(0, 1);

            requestContent = requestContent.Remove(requestContent.Length - 1, 1);
            /* Request is cleaned to have no ending brackets */

            /* Test that the request has an inner bracket pair which (should) contains the usernames */
            if (!(requestContent.Contains("[") && requestContent.IndexOf("]") > requestContent.IndexOf("[")))
            {
                throw new GCalExchangeException(GCalExchangeErrorCode.MalformedRequest,
                                                string.Format("GCalRequest exchange users section is not properly formatted: [rawInput:{0}]", rawInput));
            }

            /* Get the indexes of the start and end username brackets */
            int usersStartIndex = requestContent.IndexOf("[");
            int usersEndIndex   = requestContent.IndexOf("]");
            int usersLength     = usersEndIndex - usersStartIndex + 1;

            /* Get the usernames string from the request */
            string usersString = requestContent.Substring(usersStartIndex, usersLength);

            /* Remove it from the rest of the request */
            requestContent = requestContent.Remove(usersStartIndex, usersLength);

            /* Remove the brackets from the start and end of the username string */
            usersString = usersString.Remove(0, 1);
            usersString = usersString.Remove(usersString.Length - 1, 1);

            /* Split the usernames by comma, store them in the request object */
            exchangeUsers = usersString.Split(',');

            // Apply any domain mappings to the user names
            for (int i = 0; i < exchangeUsers.Length; i++)
            {
                string user = exchangeUsers[i].Trim();
                exchangeUsers[i] = ConfigCache.MapToLocalDomain(user);
            }

            /* Split up the rest of the request */
            string[] requestItems = requestContent.Split(',');

            /* Test that the proper amount of variables remain in the string */
            if (requestItems.Length != expectedRequestItems)
            {
                throw new GCalExchangeException(GCalExchangeErrorCode.MalformedRequest,
                                                String.Format("GCalRequest does not contain the proper amount of variables; Supplied - {0}, Expected - {1}",
                                                              requestItems.Length,
                                                              expectedRequestItems));
            }

            /* Retrieve the version and message ids */
            versionNumber = requestItems[0].Trim();
            messageId     = requestItems[1].Trim();

            /* Get the start and end date from the request, the two dates are separated by '/' */
            string dateString = requestItems[3].Trim();

            string[] dateArray = dateString.Split('/');
            if (dateArray.Length != 2)
            {
                throw new GCalExchangeException(GCalExchangeErrorCode.MalformedRequest,
                                                "GCalRequest does not contain sufficient date information, both a start and end date must be supplied");
            }

            startDate = DateUtil.ParseGoogleDate(dateArray[0].Trim());
            endDate   = DateUtil.ParseGoogleDate(dateArray[1].Trim());

            string requestItemSince = requestItems[4].Trim();

            /* Get the since field from the request */
            try
            {
                since = DateUtil.ParseGoogleDate(requestItemSince);
            }
            catch (GCalExchangeException ex)
            {
                // We don't really use this param anyway and in some cases
                // we've seen an invalid date
                log.Warn(String.Format("Ignoring incorrect since request parameter {0}",
                                       requestItemSince),
                         ex);
                since = new DateTime();
            }

            /* Get the current time zone name */
            timeZone = OlsonUtil.GetTimeZone(requestItems[5].Trim());

            utcStartDate = OlsonUtil.ConvertToUTC(startDate, timeZone);
            utcEndDate   = OlsonUtil.ConvertToUTC(endDate, timeZone);
        }
Esempio n. 3
0
        /// <summary>
        /// Merges a users appointment schedule from with appointments generated from a
        /// GoogleApps feed
        /// </summary>
        /// <param name="user">User to update with Google Apps information</param>
        /// <param name="googleAppsFeed">Source feed to generate appointment information</param>
        /// <param name="exchangeGateway">Gateway to sync Appointments with</param>
        /// <param name="window">DateRange to sync for</param>
        public void SyncUser(
            ExchangeUser user,
            EventFeed googleAppsFeed,
            ExchangeService exchangeGateway,
            DateTimeRange window)
        {
            exchangeGateway.GetCalendarInfoForUser(user, window);
            if (!user.HaveAppointmentDetail)
            {
                // Cannot sync if there is no appointment detail
                log.InfoFormat("Skipped Sync of {0} due to missing appointment lookup failure", user.Email);
                return;
            }

            List <Appointment> toUpdate = new List <Appointment>();
            List <Appointment> toDelete = new List <Appointment>();
            List <Appointment> toCreate = new List <Appointment>();

            OlsonTimeZone feedTimeZone = OlsonUtil.GetTimeZone(googleAppsFeed.TimeZone.Value);
            IntervalTree <Appointment> gcalApptTree =
                CreateAppointments(user, feedTimeZone, googleAppsFeed);

            /* Iterate through each Free/Busy time block for the user */
            foreach (FreeBusyTimeBlock fbtb in user.BusyTimes.Values)
            {
                /* Iterate through each appointment for the Free/Busy time block */
                foreach (Appointment appt in fbtb.Appointments)
                {
                    log.Debug(String.Format("Exchange @ '{0} {1}'",
                                            appt.Range,
                                            ValidateOwnership(appt)));
                    /* Validate that this is a GCalender appoint */
                    if (ValidateOwnership(appt))
                    {
                        /* If the GCalender appointments do not contain an
                         * appointment for this period, add it for deletion */
                        if (gcalApptTree.FindExact(appt.Range) == null)
                        {
                            toDelete.Add(appt);
                        }
                    }
                }
            }

            /* Iterate through each Google Apps appointment */
            AppointmentCollection appointments = user.BusyTimes.Appointments;
            List <Appointment>    gcalApptList = gcalApptTree.GetNodeList();

            foreach (Appointment newAppt in gcalApptList)
            {
                // If the meeting was cancelled
                log.DebugFormat("Looking @ {0} {1}", newAppt.Range, newAppt.Range.Start.Kind);

                if (newAppt.MeetingStatus == MeetingStatus.Cancelled)
                {
                    // Check if there is an existing appointment that matches
                    List <Appointment> matches = appointments.Get(newAppt.Range);
                    foreach (Appointment a in matches)
                    {
                        if (ValidateOwnership(a))
                        {
                            toDelete.Add(a);
                        }
                    }

                    // Work is done for this appointment, continue to next entry
                    continue;
                }

                bool updatedAppointment = false;

                List <Appointment> apptList = appointments.Get(newAppt.Range);
                log.DebugFormat("Looking up preexisting event: {0} {1}", newAppt.Range, newAppt.Range.Start.Kind);
                log.DebugFormat("Found {0} matching items", apptList.Count);

                // Check that there is a free busy block that correlates with this appointment
                foreach (Appointment existingAppt in apptList)
                {
                    if (ValidateOwnership(existingAppt) && !updatedAppointment)
                    {
                        UpdateAppointmentInfo(existingAppt, newAppt);
                        toUpdate.Add(existingAppt);
                        updatedAppointment = true;
                    }
                }

                if (!updatedAppointment)
                {
                    toCreate.Add(newAppt);
                    log.DebugFormat("ADDING '{0}' - Not an update",
                                    newAppt.Range);
                }
            }

            if (log.IsInfoEnabled)
            {
                log.InfoFormat(
                    "AppointmentWriter for '{0}'.  [{1} deleted, {2} updated, {3} new]",
                    user.Email,
                    toDelete.Count,
                    toUpdate.Count,
                    toCreate.Count);
            }

            exchangeGateway.Appointments.DeleteAppointments(user, toDelete);
            // TODO: Updates are not currently published
            // exchangeGateway.Appointments.UpdateAppointments( user, updateAppointments );
            exchangeGateway.Appointments.WriteAppointments(user, toCreate);
        }