public void RecurringComponentAttachmentTests(RecurringComponent noAttachment, RecurringComponent withAttachment) { var attachments = GetAttachments(); Assert.AreNotEqual(noAttachment, withAttachment); Assert.AreNotEqual(noAttachment.GetHashCode(), withAttachment.GetHashCode()); noAttachment.Attachments.Add(new Attachment(attachments.Item2 /*copy*/)); Assert.AreEqual(noAttachment, withAttachment); Assert.AreEqual(noAttachment.GetHashCode(), withAttachment.GetHashCode()); }
/// <summary> /// Adds all exceptions defined in the EXDATE property of the specified Recurring Component in /// the list of Exceptions of the Scheduler Recurrence Rule. /// </summary> /// <param name="schedulerRRule"><seealso cref="RecurrenceRule"/> as the Scheduler Recurrence Rule.</param> /// <param name="recurringComponent">The <seealso cref="RecurringComponent"/> object.</param> private static void AddRecurrenceExceptions(RecurrenceRule schedulerRRule, RecurringComponent recurringComponent) { if (recurringComponent.ExceptionDates != null) { foreach (IPeriodList exceptionDates in recurringComponent.ExceptionDates) { foreach (Period period in exceptionDates) { if (period.StartTime != null) { schedulerRRule.Exceptions.Add(period.StartTime.Local); } } } } }
/// <summary> /// Evaluates <see cref="Alarm"/>s for the given recurring component, <paramref name="rc"/>. /// This evaluation is based on the evaluation period for the <see cref="RecurringComponent"/>. /// </summary> /// <param name="rc">The </param> /// <returns></returns> virtual public List<AlarmOccurrence> Evaluate(RecurringComponent rc) { Occurrences = new List<AlarmOccurrence>(); // If the trigger is relative, it can recur right along with // the recurring items, otherwise, it happens once and // only once (at a precise time). if (Trigger.IsRelative) { foreach (Date_Time dt in rc.DateTimes) Occurrences.Add(new AlarmOccurrence(this, dt + Trigger.Duration, rc)); } else Occurrences.Add(new AlarmOccurrence(this, Trigger.DateTime.Copy(), rc)); // If a REPEAT and DURATION value were specified, // then handle those repetitions here. AddRepeatedItems(); return Occurrences; }
/// <summary> /// Evaluates <see cref="Alarm"/>s for the given recurring component, <paramref name="rc"/>. /// This evaluation is based on the evaluation period for the <see cref="RecurringComponent"/>. /// </summary> /// <param name="rc">The </param> /// <returns></returns> virtual public List<AlarmOccurrence> Evaluate(RecurringComponent rc) { Occurrences.Clear(); // If the trigger is relative, it can recur right along with // the recurring items, otherwise, it happens once and // only once (at a precise time). if (Trigger.IsRelative) { Duration d = null; foreach (Period p in rc.Periods) { Date_Time dt = p.StartTime; if (Trigger.Related == Trigger.TriggerRelation.END) { if (p.EndTime != null) { dt = p.EndTime; if (d == null) d = p.Duration; } // Use the "last-found" duration as a reference point else if (d != null) dt = p.StartTime + d; else throw new ArgumentException("Alarm trigger is relative to the END of the occurrence; however, the occurence has no discernible end."); } Occurrences.Add(new AlarmOccurrence(this, dt + Trigger.Duration, rc)); } } else Occurrences.Add(new AlarmOccurrence(this, Trigger.DateTime.Copy(), rc)); // If a REPEAT and DURATION value were specified, // then handle those repetitions here. AddRepeatedItems(); return Occurrences; }
static public Alarm Create(RecurringComponent rc) { Alarm alarm = (Alarm)rc.iCalendar.Create(rc, "VALARM"); return alarm; }
public AlarmOccurrence(Alarm a, Date_Time dt, RecurringComponent rc) { this.Alarm = a; this.DateTime = dt; this.Component = rc; }
public AlarmOccurrence(AlarmOccurrence ao) { this.Alarm = ao.Alarm; this.DateTime = ao.DateTime.Copy(); this.Component = ao.Component; }
public RecurringComponentSerializer(RecurringComponent rc) : base(rc) { }
/// <summary> /// Creates a Recurrence Rule in RadScheduler-friendly format from the RRule of the specified Recurring component. /// </summary> /// <param name="startDate">The Start Date of the Recurring component.</param> /// <param name="endDate">The End Date of the Recurring component.</param> /// <param name="recurringComponent">The Recurring component.</param> /// <returns>A <see cref="string"/> representation of the RRule in RadScheduler-friendly format.</returns> private static string GetSchedulerRecurrenceRule(DateTime startDate, DateTime endDate, RecurringComponent recurringComponent) { string recurrenceRuleString = String.Empty; if ((recurringComponent.RecurrenceRules != null) && (recurringComponent.RecurrenceRules[0] != null)) { RecurrenceRange schedulerRange = new RecurrenceRange(); schedulerRange.Start = startDate; schedulerRange.EventDuration = endDate - startDate; DDay.iCal.RecurrencePattern iCalPattern = (DDay.iCal.RecurrencePattern)recurringComponent.RecurrenceRules[0]; if (iCalPattern.Count > 0) { schedulerRange.MaxOccurrences = iCalPattern.Count; } else if ((iCalPattern.Until != null))//&& (iCalPattern.IsValidDate(iCalPattern.Until)) { schedulerRange.RecursUntil = iCalPattern.Until.ToLocalTime(); } RecurrenceRule schedulerRRule = null; int iCallPatternInterval = iCalPattern.Interval; RecurrenceDay schedulerRecurrenceDay = GetSchedulerRecurrenceDay(iCalPattern.ByDay); switch (iCalPattern.Frequency) { case FrequencyType.Hourly: schedulerRRule = new HourlyRecurrenceRule(iCallPatternInterval, schedulerRange); break; case FrequencyType.Daily: if (schedulerRecurrenceDay == RecurrenceDay.None) { schedulerRRule = new DailyRecurrenceRule(iCallPatternInterval, schedulerRange); } else { schedulerRRule = new DailyRecurrenceRule(schedulerRecurrenceDay, schedulerRange); } break; case FrequencyType.Weekly: if (schedulerRecurrenceDay == RecurrenceDay.None) { schedulerRRule = new WeeklyRecurrenceRule( iCallPatternInterval, (RecurrenceDay)startDate.DayOfWeek, schedulerRange, iCalPattern.FirstDayOfWeek); } else { schedulerRRule = new WeeklyRecurrenceRule( iCallPatternInterval, schedulerRecurrenceDay, schedulerRange, iCalPattern.FirstDayOfWeek); } break; case FrequencyType.Monthly: if (iCalPattern.ByMonthDay.Count > 0) { schedulerRRule = new MonthlyRecurrenceRule( iCalPattern.ByMonthDay[0], iCallPatternInterval, schedulerRange); } else if (iCalPattern.BySetPosition.Count > 0) { schedulerRRule = new MonthlyRecurrenceRule( iCalPattern.BySetPosition[0], schedulerRecurrenceDay, iCallPatternInterval, schedulerRange); } else { schedulerRRule = new MonthlyRecurrenceRule( startDate.Day, iCallPatternInterval, schedulerRange); } break; case FrequencyType.Yearly: if (iCalPattern.ByMonth.Count > 0) { if (iCalPattern.ByMonthDay.Count > 0) { schedulerRRule = new YearlyRecurrenceRule( (RecurrenceMonth)iCalPattern.ByMonth[0], iCalPattern.ByMonthDay[0], schedulerRange); } else if (iCalPattern.BySetPosition.Count > 0) { schedulerRRule = new YearlyRecurrenceRule( iCalPattern.BySetPosition[0], (RecurrenceMonth)iCalPattern.ByMonth[0], schedulerRecurrenceDay, schedulerRange); } else { schedulerRRule = new YearlyRecurrenceRule( (RecurrenceMonth)iCalPattern.ByMonth[0], startDate.Day, schedulerRange); } } else { schedulerRRule = new YearlyRecurrenceRule( (RecurrenceMonth)startDate.Month, startDate.Day, schedulerRange); } break; default: break; } if (schedulerRRule != null) { AddRecurrenceExceptions(schedulerRRule, recurringComponent); recurrenceRuleString = schedulerRRule.ToString(); } } return recurrenceRuleString; }
/// <summary> /// Function is called to create the course ics file /// Function is called everytime the course calendar needs to be updated /// </summary> /// <param name="id"></param> public void CreateCourseCalendar(int id) { //Get the Course var course = (from d in db.Courses where d.ID == id select new { d.StartDate, d.EndDate, d.Prefix, d.Number, d.Semester, d.Year, d.CourseMeetings, d.CourseBreaks, d.ID }).FirstOrDefault(); //get course events var events = (from e in db.Events where e.Poster.AbstractCourseID == ActiveCourseUser.AbstractCourseID && e.StartDate >= course.StartDate && e.StartDate <= course.EndDate && e.Approved select new { e.StartDate, e.EndDate, e.Title, e.Description }).ToList(); //Create the calendar object iCalendar courseCalendar = new iCalendar(); //initalize the Calendar object courseCalendar.AddTimeZone(DateTimeExtensions.GetTimeZone(((Course)ActiveCourseUser.AbstractCourse).TimeZoneOffset)); courseCalendar.Method = "PUBLISH"; courseCalendar.Name = "VCALENDAR"; courseCalendar.Version = "2.0"; courseCalendar.ProductID = "-//Washington State University//PLUS.OSBLE.org//EN"; courseCalendar.Scale = "GREGORIAN"; courseCalendar.AddProperty("X-WR-CALNAME", course.Prefix + "-" + course.Number + "-" + course.Semester + "-" + course.Year); //get course breaks if (ActiveCourseUser.AbstractCourse is Course && ((ActiveCourseUser.AbstractCourse as Course).ShowMeetings == true)) { foreach (CourseMeeting cm in course.CourseMeetings) { StringBuilder rpPattern = new StringBuilder("FREQ=WEEKLY;UNTIL="); rpPattern.Append(new iCalDateTime(course.EndDate.UTCToCourse(ActiveCourseUser.AbstractCourseID)).ToString(@"yyyyMMdd\THHmmss\Z")); rpPattern.Append(";WKST=SU;BYDAY="); if (cm.Sunday) { rpPattern.Append("SU,"); } if (cm.Monday) { rpPattern.Append("MO,"); } if (cm.Tuesday) { rpPattern.Append("TU,"); } if (cm.Wednesday) { rpPattern.Append("WE,"); } if (cm.Thursday) { rpPattern.Append("TH,"); } if (cm.Friday) { rpPattern.Append("FR,"); } if (cm.Saturday) { rpPattern.Append("SA"); } //trim trailing comma if it is there if (rpPattern[rpPattern.Length - 1] == ',') { rpPattern.Remove(rpPattern.Length - 1, 1); } RecurringComponent recurringComponent = new RecurringComponent(); RecurrencePattern pattern = new RecurrencePattern(rpPattern.ToString()); DDay.iCal.Event evt = courseCalendar.Create <DDay.iCal.Event>(); //may cause issues DateTime evtStart = DateTime.SpecifyKind(course.StartDate, DateTimeKind.Utc); evtStart = evtStart.Add(cm.StartTime.TimeOfDay); DateTime evtEnd = DateTime.SpecifyKind(course.StartDate, DateTimeKind.Utc); evtEnd = evtEnd.Add(cm.EndTime.TimeOfDay); //we need to test if right NOW is in DST. //case: course starts during DST, and it's now after DST, result: after DST event is now wrong. DateTime currentTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, evtStart.Hour, evtStart.Minute, evtStart.Second, DateTimeKind.Utc); bool isDaylight = TimeZoneInfo.Local.IsDaylightSavingTime(currentTime.UTCToCourse(ActiveCourseUser.AbstractCourseID)); if (isDaylight) { evt.Start = new iCalDateTime(evtStart.UTCToCourse(ActiveCourseUser.AbstractCourseID)); evt.End = new iCalDateTime(evtEnd.UTCToCourse(ActiveCourseUser.AbstractCourseID)); evt.LastModified = new iCalDateTime(DateTime.Now); evt.Summary = cm.Name; evt.Location = cm.Location; evt.RecurrenceRules.Add(pattern); } else //no longer DST { bool matchingStartDay = false; /* * if there happens to be a "meeting times" in the database without a day of the week associated with * the meeting, we need to skip the while and switch case, otherwise it's an infinite loop! */ bool meetingTimeWithoutDaysOfWeek = cm.Sunday || cm.Monday || cm.Tuesday || cm.Wednesday || cm.Thursday || cm.Friday || cm.Saturday ? false : true; int count = 0; //infinite loop protection x2! //WHILE matchingStartDay is false (default false) AND the meeting time has at least one day of the week //AND if we've hit a count of 7, that means we've already checked each day of the week and will never find one! //exit while if we fail either of these conditions! while ((!matchingStartDay && !meetingTimeWithoutDaysOfWeek) && count < 7) { switch (currentTime.DayOfWeek) //find which day of the week for this meeting { case DayOfWeek.Monday: if (cm.Monday) { matchingStartDay = true; } break; case DayOfWeek.Tuesday: if (cm.Tuesday) { matchingStartDay = true; } break; case DayOfWeek.Wednesday: if (cm.Wednesday) { matchingStartDay = true; } break; case DayOfWeek.Thursday: if (cm.Thursday) { matchingStartDay = true; } break; case DayOfWeek.Friday: if (cm.Friday) { matchingStartDay = true; } break; case DayOfWeek.Saturday: if (cm.Saturday) { matchingStartDay = true; } break; case DayOfWeek.Sunday: if (cm.Sunday) { matchingStartDay = true; } break; default: matchingStartDay = false; break; } if (!matchingStartDay) { currentTime = new DateTime(currentTime.Year, currentTime.Month, currentTime.AddDays(1).Day, evtStart.Hour, evtStart.Minute, evtStart.Second, DateTimeKind.Utc); } count++; //infinite loop protection x2! if we've reached 7 we've cycled all weekdays, so get us out of here! } //proceed only if there was a day of the week found for this course meeting time if (!meetingTimeWithoutDaysOfWeek && matchingStartDay) { evt.Start = new iCalDateTime(currentTime.UTCToCourse(ActiveCourseUser.AbstractCourseID)); evt.End = new iCalDateTime(evtEnd.UTCToCourse(ActiveCourseUser.AbstractCourseID)); evt.LastModified = new iCalDateTime(DateTime.Now); evt.Summary = cm.Name; evt.Location = cm.Location; evt.RecurrenceRules.Add(pattern); } } } //create the course breaks foreach (CourseBreak cb in course.CourseBreaks) { DDay.iCal.Event evt = courseCalendar.Create <DDay.iCal.Event>(); DateTime evtStart = cb.StartDate.Date; DateTime evtEnd = cb.EndDate.Date.AddDays(1); evt.Summary = cb.Name; evt.Start = new iCalDateTime(evtStart); evt.End = new iCalDateTime(evtEnd); evt.LastModified = new iCalDateTime(DateTime.Now); } }//end if //add all the events to the calendar foreach (var e in events) { DDay.iCal.Event evt = courseCalendar.Create <DDay.iCal.Event>(); evt.Start = new iCalDateTime(e.StartDate.UTCToCourse(ActiveCourseUser.AbstractCourseID)); if (e.EndDate == null) { evt.End = new iCalDateTime(e.StartDate.UTCToCourse(ActiveCourseUser.AbstractCourseID)); evt.End.AddMinutes(1); } else { evt.End = new iCalDateTime(((DateTime)e.EndDate).UTCToCourse(ActiveCourseUser.AbstractCourseID)); } evt.Summary = e.Title; if (e.Description != null) { evt.Description = e.Description; } } // Create a serialization context and serializer factory. // These will be used to build the serializer for our object. ISerializationContext ctx = new SerializationContext(); ISerializerFactory factory = new DDay.iCal.Serialization.iCalendar.SerializerFactory(); // Get a serializer for our object IStringSerializer serializer = factory.Build(courseCalendar.GetType(), ctx) as IStringSerializer; string output = serializer.SerializeToString(courseCalendar); var bytes = Encoding.UTF8.GetBytes(output); SaveCourseCalendar(bytes, course.ID); }
/// <summary> /// Creates a Recurrence Rule in RadScheduler-friendly format from the RRule of the specified Recurring component. /// </summary> /// <param name="startDate">The Start Date of the Recurring component.</param> /// <param name="endDate">The End Date of the Recurring component.</param> /// <param name="recurringComponent">The Recurring component.</param> /// <returns>A <see cref="string"/> representation of the RRule in RadScheduler-friendly format.</returns> private static string GetSchedulerRecurrenceRule(DateTime startDate, DateTime endDate, RecurringComponent recurringComponent) { string recurrenceRuleString = String.Empty; if ((recurringComponent.RecurrenceRules != null) && (recurringComponent.RecurrenceRules[0] != null)) { RecurrenceRange schedulerRange = new RecurrenceRange(); schedulerRange.Start = startDate; schedulerRange.EventDuration = endDate - startDate; DDay.iCal.RecurrencePattern iCalPattern = (DDay.iCal.RecurrencePattern)recurringComponent.RecurrenceRules[0]; if (iCalPattern.Count > 0) { schedulerRange.MaxOccurrences = iCalPattern.Count; } else if ((iCalPattern.Until != null))//&& (iCalPattern.IsValidDate(iCalPattern.Until)) { schedulerRange.RecursUntil = iCalPattern.Until.ToLocalTime(); } RecurrenceRule schedulerRRule = null; int iCallPatternInterval = iCalPattern.Interval; RecurrenceDay schedulerRecurrenceDay = GetSchedulerRecurrenceDay(iCalPattern.ByDay); switch (iCalPattern.Frequency) { case FrequencyType.Hourly: schedulerRRule = new HourlyRecurrenceRule(iCallPatternInterval, schedulerRange); break; case FrequencyType.Daily: if (schedulerRecurrenceDay == RecurrenceDay.None) { schedulerRRule = new DailyRecurrenceRule(iCallPatternInterval, schedulerRange); } else { schedulerRRule = new DailyRecurrenceRule(schedulerRecurrenceDay, schedulerRange); } break; case FrequencyType.Weekly: if (schedulerRecurrenceDay == RecurrenceDay.None) { schedulerRRule = new WeeklyRecurrenceRule( iCallPatternInterval, (RecurrenceDay)startDate.DayOfWeek, schedulerRange, iCalPattern.FirstDayOfWeek); } else { schedulerRRule = new WeeklyRecurrenceRule( iCallPatternInterval, schedulerRecurrenceDay, schedulerRange, iCalPattern.FirstDayOfWeek); } break; case FrequencyType.Monthly: if (iCalPattern.ByMonthDay.Count > 0) { schedulerRRule = new MonthlyRecurrenceRule( iCalPattern.ByMonthDay[0], iCallPatternInterval, schedulerRange); } else if (iCalPattern.BySetPosition.Count > 0) { schedulerRRule = new MonthlyRecurrenceRule( iCalPattern.BySetPosition[0], schedulerRecurrenceDay, iCallPatternInterval, schedulerRange); } else { schedulerRRule = new MonthlyRecurrenceRule( startDate.Day, iCallPatternInterval, schedulerRange); } break; case FrequencyType.Yearly: if (iCalPattern.ByMonth.Count > 0) { if (iCalPattern.ByMonthDay.Count > 0) { schedulerRRule = new YearlyRecurrenceRule( (RecurrenceMonth)iCalPattern.ByMonth[0], iCalPattern.ByMonthDay[0], schedulerRange); } else if (iCalPattern.BySetPosition.Count > 0) { schedulerRRule = new YearlyRecurrenceRule( iCalPattern.BySetPosition[0], (RecurrenceMonth)iCalPattern.ByMonth[0], schedulerRecurrenceDay, schedulerRange); } else { schedulerRRule = new YearlyRecurrenceRule( (RecurrenceMonth)iCalPattern.ByMonth[0], startDate.Day, schedulerRange); } } else { schedulerRRule = new YearlyRecurrenceRule( (RecurrenceMonth)startDate.Month, startDate.Day, schedulerRange); } break; default: break; } if (schedulerRRule != null) { AddRecurrenceExceptions(schedulerRRule, recurringComponent); recurrenceRuleString = schedulerRRule.ToString(); } } return(recurrenceRuleString); }