示例#1
0
        public string GetAsICalFormat(IEnumerable <Event> events, string calendarName, string calenderDescription)
        {
            var calendar = new Calendar {
                Method     = "PUBLISH",
                TimeZones  = { new VTimeZone("Europe/Amsterdam") },
                Properties =
                {
                    new CalendarProperty("X-PUBLISHED-TTL", "PT15M"),
                    new CalendarProperty("X-WR-TIMEZONE",   "Europe/Amsterdam"),
                    new CalendarProperty("X-WR-CALNAME",    calendarName),
                    new CalendarProperty("X-WR-CALDESC",    calenderDescription),
                }
            };

            calendar.AddTimeZone("Europe/Amsterdam");


            foreach (var @event in events.Where(x => x.Start.DateTime != null && x.End.DateTime != null))
            {
                if ([email protected] || [email protected])
                {
                    continue;
                }
                calendar.Events.Add(new CalendarEvent
                {
                    Description = @event.Description,
                    Summary     = @event.Summary,
                    Location    = @event.Location,
                    Attendees   = @event.Attendees == null
                        ? new List <Attendee>()
                        : @event.Attendees.Select(x => new Attendee {
                        CommonName = x.DisplayName, Value = new Uri($"mailto:{x.Email}")
                    }).ToList(),
                    Organizer = @event.Organizer == null
                        ? null
                        : new Organizer {
                        CommonName = @event.Organizer.DisplayName, Value = new Uri($"mailto:{@event.Organizer.Email}"), SentBy = new Uri($"mailto:{@event.Organizer.Email}")
                    },
                    Start = new CalDateTime(@event.Start.DateTime.Value),
                    End   = new CalDateTime(@event.End.DateTime.Value),
                });
            }

            var serializer = new CalendarSerializer();

            return(serializer.SerializeToString(calendar));
        }
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            if (!Page.User.Identity.IsAuthenticated)
            {
                throw new MyFlightbookException("Unauthorized!");
            }

            int idClub = util.GetIntParam(Request, "c", 0);
            if (idClub == 0)
            {
                throw new MyFlightbookException("Invalid club");
            }

            Club c = Club.ClubWithID(idClub);

            if (c == null)
            {
                throw new MyFlightbookException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Invalid club: {0}", idClub));
            }

            string   szIDs  = util.GetStringParam(Request, "sid");
            string[] rgSIDs = szIDs.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            if (rgSIDs.Length == 0)
            {
                throw new MyFlightbookException("No scheduled events to download specified");
            }

            bool fIsAdmin = c.HasAdmin(Page.User.Identity.Name);

            using (Ical.Net.Calendar ic = new Ical.Net.Calendar())
            {
                ic.AddTimeZone(new VTimeZone(c.TimeZone.Id));

                string szTitle = string.Empty;

                foreach (string sid in rgSIDs)
                {
                    ScheduledEvent se = ScheduledEvent.AppointmentByID(sid, c.TimeZone);

                    if (se == null)
                    {
                        throw new MyFlightbookException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Invalid scheduled event ID: {0}", sid));
                    }

                    if (!fIsAdmin && Page.User.Identity.Name.CompareOrdinal(se.OwningUser) != 0)
                    {
                        throw new MyFlightbookException("Attempt to download appointment that you don't own!");
                    }

                    ClubAircraft ca = c.MemberAircraft.FirstOrDefault(ca2 => ca2.AircraftID.ToString(System.Globalization.CultureInfo.InvariantCulture).CompareOrdinal(se.ResourceID) == 0);

                    Event ev = ic.Create <Event>();
                    ev.Uid           = se.ID;
                    ev.IsAllDay      = false;
                    ev.Start         = new CalDateTime(se.StartUtc, TimeZoneInfo.Utc.Id);
                    ev.End           = new CalDateTime(se.EndUtc, TimeZoneInfo.Utc.Id);
                    ev.Start.HasTime = ev.End.HasTime = true;   // has time is false if the ultimate time is midnight.
                    szTitle          = ev.Description = ev.Summary = String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0}{1}", ca == null ? string.Empty : String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} - ", ca.DisplayTailnumber), se.Body);
                    ev.Location      = c.HomeAirport == null ? c.HomeAirportCode : String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} - {1}", c.HomeAirportCode, c.HomeAirport.Name);

                    Alarm a = new Alarm();
                    a.Action           = AlarmAction.Display;
                    a.Description      = ev.Summary;
                    a.Trigger          = new Trigger();
                    a.Trigger.DateTime = ev.Start.AddMinutes(-30);
                    ev.Alarms.Add(a);

                    ic.Method = "PUBLISH";
                }

                CalendarSerializer s = new CalendarSerializer();

                string output = s.SerializeToString(ic);
                Page.Response.Clear();
                Page.Response.ContentType = "text/calendar";
                Response.AddHeader("Content-Disposition", String.Format(System.Globalization.CultureInfo.InvariantCulture, "inline;filename={0}", Branding.ReBrand(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}appt.ics", szTitle)).Replace(" ", "-")));
                Response.Write(output);
                Response.Flush();
                Response.End();
            }
        }
    }
示例#3
0
        /// <summary>
        /// Creates the iCalendar object and populates it with events
        /// </summary>
        /// <param name="calendarProps">The calendar props.</param>
        /// <returns></returns>
        private Calendar CreateICalendar(CalendarProps calendarProps, string interactionDeviceType)
        {
            // Get a list of confirmed attendances filtered by calendarProps
            List <Attendance> attendances = GetAttendances(calendarProps);

            // Create the iCalendar
            var icalendar = new Calendar();

            icalendar.AddTimeZone(TimeZoneInfo.Local);
            TimeSpan duration          = TimeSpan.MinValue;
            int      currentScheduleId = -1;

            // Create each of the attendances
            foreach (var attendance in attendances)
            {
                using (var rockContext = new RockContext())
                {
                    var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);

                    var schedule = attendanceOccurrenceService
                                   .Queryable()
                                   .AsNoTracking()
                                   .Where(a => a.Id == attendance.OccurrenceId)
                                   .Select(a => a.Schedule)
                                   .FirstOrDefault();

                    string scheduleName = schedule.Name;

                    // TODO: Construct a description that includes the group leader contact info and the URL to the schedule toolbox.
                    string description = schedule.Description;

                    string locationName = attendanceOccurrenceService
                                          .Queryable()
                                          .AsNoTracking()
                                          .Where(a => a.Id == attendance.OccurrenceId)
                                          .Select(a => a.Location.Name)
                                          .FirstOrDefault() ?? string.Empty;

                    if (schedule.Id != currentScheduleId)
                    {
                        // We have to get the duration from Schedule.iCal for this attendance.
                        // Attendances are ordered by scheduleId so this only happens once for each unique schedule.
                        var serializer = new CalendarSerializer();
                        var ical       = ( CalendarCollection )serializer.Deserialize(schedule.iCalendarContent.ToStreamReader());
                        duration          = ical[0].Events[0].Duration;
                        currentScheduleId = schedule.Id;
                    }

                    var iCalEvent = new Event();
                    iCalEvent.Summary  = scheduleName;
                    iCalEvent.Location = locationName;
                    iCalEvent.DtStart  = new CalDateTime(attendance.StartDateTime, icalendar.TimeZones[0].TzId);
                    iCalEvent.Duration = duration;

                    // Don't set the description prop for outlook to force it to use the X-ALT-DESC property which can have markup.
                    if (interactionDeviceType != "Outlook")
                    {
                        iCalEvent.Description = description.ConvertBrToCrLf().SanitizeHtml();
                    }

                    // HTML version of the description for outlook
                    iCalEvent.AddProperty("X-ALT-DESC;FMTTYPE=text/html", "<html>" + description + "</html>");

                    // classification: "PUBLIC", "PRIVATE", "CONFIDENTIAL"
                    iCalEvent.Class = "PUBLIC";

                    //Add contact info for the group leader
                    int groupId = attendanceOccurrenceService
                                  .Queryable()
                                  .AsNoTracking()
                                  .Where(a => a.Id == attendance.OccurrenceId)
                                  .Select(a => a.GroupId)
                                  .FirstOrDefault() ?? -1;

                    Person groupLeader = new GroupMemberService(rockContext).GetLeaders(groupId).AsNoTracking().Select(m => m.Person).FirstOrDefault() ?? null;

                    if (groupLeader != null)
                    {
                        iCalEvent.Organizer            = new Organizer(string.Format("MAILTO:{0}", groupLeader.Email));
                        iCalEvent.Organizer.CommonName = groupLeader.FullName;

                        // Outlook doesn't seem to use Contacts or Comments
                        string contactName  = !string.IsNullOrEmpty(groupLeader.FullName) ? "Name: " + groupLeader.FullName : string.Empty;
                        string contactEmail = !string.IsNullOrEmpty(groupLeader.Email) ? ", Email: " + groupLeader.Email : string.Empty;
                        string contactInfo  = contactName + contactEmail;

                        iCalEvent.Contacts.Add(contactInfo);
                        iCalEvent.Comments.Add(contactInfo);
                    }

                    icalendar.Events.Add(iCalEvent);
                }
            }

            return(icalendar);
        }
        /// <summary>
        /// Creates the iCalendar object and populates it with events
        /// </summary>
        /// <param name="calendarProps">The calendar props.</param>
        /// <returns></returns>
        private Calendar CreateICalendar(CalendarProps calendarProps)
        {
            // Get a list of Rock Calendar Events filtered by calendarProps
            List <EventItem> eventItems = GetEventItems(calendarProps);

            // Create the iCalendar.
            // Allow ICal to create the VTimeZone object from the local time zone to ensure that we get the correct name and daylight saving offset.
            var icalendar = new Calendar();

            var vtz = VTimeZone.FromLocalTimeZone();

            icalendar.AddTimeZone(vtz);

            var timeZoneId = vtz.TzId;

            // Create each of the events for the calendar(s)
            foreach (EventItem eventItem in eventItems)
            {
                foreach (EventItemOccurrence occurrence in eventItem.EventItemOccurrences)
                {
                    if (occurrence.Schedule == null)
                    {
                        continue;
                    }

                    var serializer = new CalendarSerializer();
                    var ical       = (CalendarCollection)serializer.Deserialize(occurrence.Schedule.iCalendarContent.ToStreamReader());

                    foreach (var icalEvent in ical[0].Events)
                    {
                        // We get all of the schedule info from Schedule.iCalendarContent
                        var ievent = icalEvent.Copy <Ical.Net.Event>();

                        ievent.Summary  = !string.IsNullOrEmpty(eventItem.Name) ? eventItem.Name : string.Empty;
                        ievent.Location = !string.IsNullOrEmpty(occurrence.Location) ? occurrence.Location : string.Empty;

                        // Create the list of exceptions.
                        // Exceptions must meet RFC 5545 iCalendar specifications to be correctly processed by third-party calendar applications
                        // such as Microsoft Outlook and Google Calendar. Specifically, an exception must have exactly the same start time
                        // and time zone as the template event, and the time zone must be expressed as an IANA name.
                        // The most recent version of iCal.Net (v2.3.5) that supports .NET framework v4.5.2 has some inconsistencies in the
                        // iCalendar serialization process, so we need to force the Start, End and Exception dates to render in exactly the same format.
                        ievent.Start = new CalDateTime(icalEvent.Start.Value, timeZoneId);
                        ievent.Start.IsUniversalTime = false;

                        ievent.End = new CalDateTime(icalEvent.End.Value, timeZoneId);
                        ievent.End.IsUniversalTime = false;

                        var eventStartTime = new TimeSpan(ievent.DtStart.Hour, ievent.DtStart.Minute, ievent.DtStart.Second);

                        var newExceptionDatesList = new List <Ical.Net.Interfaces.DataTypes.IPeriodList>();

                        foreach (var exceptionDateList in ievent.ExceptionDates)
                        {
                            var newDateList = new PeriodList()
                            {
                                TzId = timeZoneId
                            };

                            foreach (var exceptionDate in exceptionDateList)
                            {
                                var newDateTime = exceptionDate.StartTime.HasTime ? exceptionDate.StartTime.Value : exceptionDate.StartTime.Value.Add(eventStartTime);

                                newDateTime = new DateTime(newDateTime.Year, newDateTime.Month, newDateTime.Day, newDateTime.Hour, newDateTime.Minute, newDateTime.Second, newDateTime.Millisecond, DateTimeKind.Local);

                                var newDate = new CalDateTime(newDateTime);
                                newDate.IsUniversalTime = false;

                                newDateList.Add(newDate);
                            }

                            newExceptionDatesList.Add(newDateList);
                        }

                        ievent.ExceptionDates = newExceptionDatesList;

                        // Rock has more descriptions than iCal so lets concatenate them
                        string description = CreateEventDescription(eventItem, occurrence);

                        // Don't set the description prop for outlook to force it to use the X-ALT-DESC property which can have markup.
                        if (interactionDeviceType != "Outlook")
                        {
                            ievent.Description = description.ConvertBrToCrLf()
                                                 .Replace("</P>", "")
                                                 .Replace("</p>", "")
                                                 .Replace("<P>", Environment.NewLine)
                                                 .Replace("<p>", Environment.NewLine)
                                                 .Replace("&nbsp;", " ")
                                                 .SanitizeHtml();
                        }

                        // HTML version of the description for outlook
                        ievent.AddProperty("X-ALT-DESC;FMTTYPE=text/html", "<html>" + description + "</html>");

                        // classification: "PUBLIC", "PRIVATE", "CONFIDENTIAL"
                        ievent.Class = "PUBLIC";

                        if (!string.IsNullOrEmpty(eventItem.DetailsUrl))
                        {
                            Uri result;
                            if (Uri.TryCreate(eventItem.DetailsUrl, UriKind.Absolute, out result))
                            {
                                ievent.Url = result;
                            }
                            else if (Uri.TryCreate("http://" + eventItem.DetailsUrl, UriKind.Absolute, out result))
                            {
                                ievent.Url = result;
                            }
                        }

                        // add contact info if it exists
                        if (occurrence.ContactPersonAlias != null)
                        {
                            ievent.Organizer            = new Organizer(string.Format("MAILTO:{0}", occurrence.ContactPersonAlias.Person.Email));
                            ievent.Organizer.CommonName = occurrence.ContactPersonAlias.Person.FullName;

                            // Outlook doesn't seems to use Contacts or Comments
                            string contactName  = !string.IsNullOrEmpty(occurrence.ContactPersonAlias.Person.FullName) ? "Name: " + occurrence.ContactPersonAlias.Person.FullName : string.Empty;
                            string contactEmail = !string.IsNullOrEmpty(occurrence.ContactEmail) ? ", Email: " + occurrence.ContactEmail : string.Empty;
                            string contactPhone = !string.IsNullOrEmpty(occurrence.ContactPhone) ? ", Phone: " + occurrence.ContactPhone : string.Empty;
                            string contactInfo  = contactName + contactEmail + contactPhone;

                            ievent.Contacts.Add(contactInfo);
                            ievent.Comments.Add(contactInfo);
                        }

                        // TODO: categories - comma delimited list of whatever, might use audience
                        foreach (var a in eventItem.EventItemAudiences)
                        {
                            ievent.Categories.Add(a.DefinedValue.Value);
                        }

                        //// No attachments for now.
                        ////if ( eventItem.PhotoId != null )
                        ////{
                        ////    // The DDay Attachment obj doesn't allow you to name the attachment. Nice huh? So just add prop manually...
                        ////    ievent.AddProperty( "ATTACH;VALUE=BINARY;ENCODING=BASE64;X-FILENAME=\"" + eventItem.Photo.FileName + "\"", Convert.ToBase64String( eventItem.Photo.ContentStream.ReadBytesToEnd().ToArray() ) );
                        ////}

                        icalendar.Events.Add(ievent);
                    }
                }
            }

            return(icalendar);
        }
示例#5
0
        public string GetCalendar()
        {
            var now    = DateTime.Now;
            var estart = now.AddDays(1);
            var eend   = now.AddMinutes(30);


            var calendar = new Ical.Net.Calendar();
            IList <Attendee> attendees = new List <Attendee>();

            Organizer orgniser = new Organizer
            {
                CommonName = "Face My Resume",
                Value      = new Uri($"mailto:[email protected]")
            };

            //attendees.Add(new Attendee("MAILTO:[email protected]")
            //{
            //    CommonName = "Siva Shankaran",
            //    Role = ParticipationRole.RequiredParticipant,
            //    ParticipationStatus = ToDoParticipationStatus.Tentative,
            //    Rsvp = true,
            //    Type = "INDIVIDUAL"
            //});

            attendees.Add(new Attendee("MAILTO:[email protected]")
            {
                //Role = ParticipationRole.RequiredParticipant,
                //ParticipationStatus = ToDoParticipationStatus.Tentative,
                //Rsvp = true,
                //Type = "INDIVIDUAL"
            });


            Alarm ealarm = new Alarm();

            ealarm.Action  = AlarmAction.Display;
            ealarm.Trigger = new Trigger(TimeSpan.FromMinutes(-30));

            const string eTz      = "Eastern Standard Time";
            var          tzi      = TimeZoneInfo.FindSystemTimeZoneById(eTz);
            var          timezone = VTimeZone.FromSystemTimeZone(tzi);

            calendar.AddTimeZone(timezone);
            //  calendar.AddTimeZone(new VTimeZone("America/New_York"));
            calendar.Method = "REQUEST";
            var e = new CalendarEvent
            {
                Start        = new CalDateTime(estart),
                End          = new CalDateTime(eend),
                LastModified = new CalDateTime(now),
                Location     = "",
                Alarms       = { ealarm },
                Sequence     = 0,
                Summary      = "Telephonic Interview",
                Description  = "Calendar sent using Face My Resume App",
                Status       = "CONFIRMED",
                Attendees    = attendees,
                Organizer    = orgniser
            };

            calendar.Events.Add(e);

            var e2 = new CalendarEvent
            {
                Start        = new CalDateTime(eend),
                End          = new CalDateTime(eend),
                LastModified = new CalDateTime(now),
                Location     = "",
                Alarms       = { ealarm },
                Sequence     = 0,
                Summary      = "InPerson Interview",
                Description  = "Calendar sent using Face My Resume App",
                Status       = "CONFIRMED",
                Attendees    = attendees,
                Organizer    = orgniser
            };
            //calendar.Events.Add(e2);


            var serializer         = new CalendarSerializer();
            var serializedCalendar = serializer.SerializeToString(calendar);

            //return serializedCalendar.Replace("github.com/rianjs/","facemyresume.com/app/").Replace("ical.net", "cal");
            return(serializedCalendar.Replace("\n ", ""));
        }