ri_cal 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. data/History.txt +10 -0
  2. data/Manifest.txt +23 -3
  3. data/lib/ri_cal.rb +28 -16
  4. data/lib/ri_cal/component.rb +11 -7
  5. data/lib/ri_cal/component/alarm.rb +0 -2
  6. data/lib/ri_cal/component/calendar.rb +0 -2
  7. data/lib/ri_cal/component/event.rb +0 -2
  8. data/lib/ri_cal/component/freebusy.rb +0 -2
  9. data/lib/ri_cal/component/journal.rb +0 -3
  10. data/lib/ri_cal/component/non_standard.rb +0 -2
  11. data/lib/ri_cal/component/timezone.rb +5 -5
  12. data/lib/ri_cal/component/timezone/timezone_period.rb +0 -2
  13. data/lib/ri_cal/component/todo.rb +0 -2
  14. data/lib/ri_cal/core_extensions.rb +8 -3
  15. data/lib/ri_cal/core_extensions/array.rb +1 -1
  16. data/lib/ri_cal/core_extensions/date.rb +3 -3
  17. data/lib/ri_cal/core_extensions/date_time.rb +4 -4
  18. data/lib/ri_cal/core_extensions/object.rb +1 -1
  19. data/lib/ri_cal/core_extensions/string.rb +1 -1
  20. data/lib/ri_cal/core_extensions/time.rb +5 -4
  21. data/lib/ri_cal/fast_date_time.rb +1 -1
  22. data/lib/ri_cal/{invalid_timezone_identifer.rb → invalid_timezone_identifier.rb} +0 -0
  23. data/lib/ri_cal/properties.rb +12 -0
  24. data/lib/ri_cal/property_value.rb +14 -5
  25. data/lib/ri_cal/property_value/duration.rb +1 -1
  26. data/lib/ri_cal/property_value/recurrence_rule.rb +13 -4
  27. data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +16 -13
  28. data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +1 -1
  29. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb +134 -0
  30. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb +82 -0
  31. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb +31 -0
  32. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb +32 -0
  33. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb +52 -0
  34. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb +31 -0
  35. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb +34 -0
  36. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb +32 -0
  37. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb +65 -0
  38. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb +31 -0
  39. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb +28 -0
  40. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb +71 -0
  41. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb +23 -0
  42. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb +96 -0
  43. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb +23 -0
  44. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb +33 -0
  45. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb +39 -0
  46. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb +28 -0
  47. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb +37 -0
  48. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb +57 -0
  49. data/lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb +42 -0
  50. data/ri_cal.gemspec +3 -3
  51. metadata +25 -5
  52. data/lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb +0 -793
  53. data/sample_ical_files/from_ical_dot_app/test1.ics +0 -38
@@ -0,0 +1,37 @@
1
+ module RiCal
2
+ class PropertyValue
3
+ class RecurrenceRule < PropertyValue
4
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
5
+ #
6
+ class OccurrenceIncrementer # :nodoc:
7
+ class WeeklyIncrementer < FrequencyIncrementer #:nodoc:
8
+
9
+ attr_reader :wkst
10
+
11
+ # include WeeklyBydayMethods
12
+
13
+ def initialize(rrule, parent)
14
+ @wkst = rrule.wkst_day
15
+ super(rrule, parent)
16
+ end
17
+
18
+ def self.for_rrule(rrule)
19
+ conditional_incrementer(rrule, "WEEKLY", ByDayIncrementer)
20
+ end
21
+
22
+ def multiplier
23
+ 7
24
+ end
25
+
26
+ def advance_what
27
+ :days
28
+ end
29
+
30
+ def end_of_occurrence(date_time)
31
+ date_time.end_of_week_with_wkst(wkst)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,57 @@
1
+ module RiCal
2
+ class PropertyValue
3
+ class RecurrenceRule < PropertyValue
4
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
5
+ #
6
+ class OccurrenceIncrementer # :nodoc:
7
+ class YearlyIncrementer < FrequencyIncrementer #:nodoc:
8
+
9
+ attr_reader :wkst
10
+
11
+ def initialize(rrule, sub_cycle_incrementer)
12
+ @wkst = rrule.wkst_day
13
+ super(rrule, sub_cycle_incrementer)
14
+ end
15
+
16
+ def self.from_rrule(rrule, start_time)
17
+ conditional_incrementer(rrule, "YEARLY", ByMonthIncrementer)
18
+ end
19
+
20
+ def advance_what
21
+ :years
22
+ end
23
+
24
+ def step(date_time)
25
+ if contains_weeknum_incrementer?
26
+ result = date_time
27
+ multiplier.times do
28
+ result = result.at_start_of_next_iso_year(wkst)
29
+ end
30
+ result
31
+ else
32
+ super(date_time)
33
+ end
34
+ end
35
+
36
+ def start_of_cycle(date_time)
37
+ if contains_weeknum_incrementer?
38
+ date_time.at_start_of_iso_year(wkst)
39
+ elsif contains_daily_incrementer?
40
+ date_time.change(:month => 1, :day => 1)
41
+ else
42
+ date_time.change(:month => 1)
43
+ end
44
+ end
45
+
46
+ def end_of_occurrence(date_time)
47
+ if contains_weeknum_incrementer?
48
+ date_time.end_of_iso_year(wkst)
49
+ else
50
+ date_time.end_of_year
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,42 @@
1
+ module RiCal
2
+ class PropertyValue
3
+ class RecurrenceRule < PropertyValue
4
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
5
+ #
6
+ module TimeManipulation #:nodoc:
7
+
8
+ def advance_day(date_time)
9
+ date_time.advance(:days => 1)
10
+ end
11
+
12
+ def first_hour_of_day(date_time)
13
+ date_time.change(:hour => 0)
14
+ end
15
+
16
+ def advance_week(date_time)
17
+ date_time.advance(:days => 7)
18
+ end
19
+
20
+ def first_day_of_week(wkst_day, date_time)
21
+ date_time.at_start_of_week_with_wkst(wkst_day)
22
+ end
23
+
24
+ def advance_month(date_time)
25
+ date_time.advance(:months => 1)
26
+ end
27
+
28
+ def first_day_of_month(date_time)
29
+ date_time.change(:day => 1)
30
+ end
31
+
32
+ def advance_year(date_time)
33
+ date_time.advance(:years => 1)
34
+ end
35
+
36
+ def first_day_of_year(date_time)
37
+ date_time.change(:month => 1, :day => 1)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
data/ri_cal.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{ri_cal}
5
- s.version = "0.8.2" #comment to trigger github rebuild
5
+ s.version = "0.8.4"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["author=Rick DeNatale"]
9
- s.date = %q{2009-09-04}
9
+ s.date = %q{2009-09-18}
10
10
  s.default_executable = %q{ri_cal}
11
11
  s.description = %q{A new Ruby implementation of RFC2445 iCalendar.
12
12
 
@@ -19,7 +19,7 @@ A Google group for discussion of this library has been set up http://groups.goog
19
19
  s.email = ["rick.denatale@gmail.com"]
20
20
  s.executables = ["ri_cal"]
21
21
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt"]
22
- s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/ri_cal", "component_attributes/alarm.yml", "component_attributes/calendar.yml", "component_attributes/component_property_defs.yml", "component_attributes/event.yml", "component_attributes/freebusy.yml", "component_attributes/journal.yml", "component_attributes/timezone.yml", "component_attributes/timezone_period.yml", "component_attributes/todo.yml", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt", "docs/rfc2445.pdf", "lib/ri_cal.rb", "lib/ri_cal/component.rb", "lib/ri_cal/component/alarm.rb", "lib/ri_cal/component/calendar.rb", "lib/ri_cal/component/event.rb", "lib/ri_cal/component/freebusy.rb", "lib/ri_cal/component/journal.rb", "lib/ri_cal/component/non_standard.rb", "lib/ri_cal/component/t_z_info_timezone.rb", "lib/ri_cal/component/timezone.rb", "lib/ri_cal/component/timezone/daylight_period.rb", "lib/ri_cal/component/timezone/standard_period.rb", "lib/ri_cal/component/timezone/timezone_period.rb", "lib/ri_cal/component/todo.rb", "lib/ri_cal/core_extensions.rb", "lib/ri_cal/core_extensions/array.rb", "lib/ri_cal/core_extensions/array/conversions.rb", "lib/ri_cal/core_extensions/date.rb", "lib/ri_cal/core_extensions/date/conversions.rb", "lib/ri_cal/core_extensions/date_time.rb", "lib/ri_cal/core_extensions/date_time/conversions.rb", "lib/ri_cal/core_extensions/object.rb", "lib/ri_cal/core_extensions/object/conversions.rb", "lib/ri_cal/core_extensions/string.rb", "lib/ri_cal/core_extensions/string/conversions.rb", "lib/ri_cal/core_extensions/time.rb", "lib/ri_cal/core_extensions/time/calculations.rb", "lib/ri_cal/core_extensions/time/conversions.rb", "lib/ri_cal/core_extensions/time/tzid_access.rb", "lib/ri_cal/core_extensions/time/week_day_predicates.rb", "lib/ri_cal/fast_date_time.rb", "lib/ri_cal/floating_timezone.rb", "lib/ri_cal/invalid_property_value.rb", "lib/ri_cal/invalid_timezone_identifer.rb", "lib/ri_cal/occurrence_enumerator.rb", "lib/ri_cal/occurrence_period.rb", "lib/ri_cal/parser.rb", "lib/ri_cal/properties/alarm.rb", "lib/ri_cal/properties/calendar.rb", "lib/ri_cal/properties/event.rb", "lib/ri_cal/properties/freebusy.rb", "lib/ri_cal/properties/journal.rb", "lib/ri_cal/properties/timezone.rb", "lib/ri_cal/properties/timezone_period.rb", "lib/ri_cal/properties/todo.rb", "lib/ri_cal/property_value.rb", "lib/ri_cal/property_value/array.rb", "lib/ri_cal/property_value/cal_address.rb", "lib/ri_cal/property_value/date.rb", "lib/ri_cal/property_value/date_time.rb", "lib/ri_cal/property_value/date_time/additive_methods.rb", "lib/ri_cal/property_value/date_time/time_machine.rb", "lib/ri_cal/property_value/date_time/timezone_support.rb", "lib/ri_cal/property_value/duration.rb", "lib/ri_cal/property_value/geo.rb", "lib/ri_cal/property_value/integer.rb", "lib/ri_cal/property_value/occurrence_list.rb", "lib/ri_cal/property_value/period.rb", "lib/ri_cal/property_value/recurrence_rule.rb", "lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb", "lib/ri_cal/property_value/recurrence_rule/enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb", "lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/numbered_span.rb", "lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb", "lib/ri_cal/property_value/recurrence_rule/validations.rb", "lib/ri_cal/property_value/text.rb", "lib/ri_cal/property_value/uri.rb", "lib/ri_cal/property_value/utc_offset.rb", "lib/ri_cal/required_timezones.rb", "performance/empty_propval/subject.rb", "performance/paris_eastern/subject.rb", "performance/penultimate_weekday/subject.rb", "performance/psm_big_enum/ical.ics", "performance/psm_big_enum/subject.rb", "performance/utah_cycling/subject.rb", "ri_cal.gemspec", "sample_ical_files/from_ical_dot_app/test1.ics", "script/benchmark_subject", "script/console", "script/destroy", "script/generate", "script/profile_subject", "script/txt2html", "spec/ri_cal/bugreports_spec.rb", "spec/ri_cal/component/alarm_spec.rb", "spec/ri_cal/component/calendar_spec.rb", "spec/ri_cal/component/event_spec.rb", "spec/ri_cal/component/freebusy_spec.rb", "spec/ri_cal/component/journal_spec.rb", "spec/ri_cal/component/t_z_info_timezone_spec.rb", "spec/ri_cal/component/timezone_spec.rb", "spec/ri_cal/component/todo_spec.rb", "spec/ri_cal/component_spec.rb", "spec/ri_cal/core_extensions/string/conversions_spec.rb", "spec/ri_cal/core_extensions/time/calculations_spec.rb", "spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb", "spec/ri_cal/fast_date_time_spec.rb", "spec/ri_cal/occurrence_enumerator_spec.rb", "spec/ri_cal/parser_spec.rb", "spec/ri_cal/property_value/date_spec.rb", "spec/ri_cal/property_value/date_time_spec.rb", "spec/ri_cal/property_value/duration_spec.rb", "spec/ri_cal/property_value/occurrence_list_spec.rb", "spec/ri_cal/property_value/period_spec.rb", "spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb", "spec/ri_cal/property_value/recurrence_rule_spec.rb", "spec/ri_cal/property_value/text_spec.rb", "spec/ri_cal/property_value/utc_offset_spec.rb", "spec/ri_cal/property_value_spec.rb", "spec/ri_cal/required_timezones_spec.rb", "spec/ri_cal_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/gem_loader/load_active_support.rb", "tasks/gem_loader/load_tzinfo_gem.rb", "tasks/ri_cal.rake", "tasks/spec.rake"]
22
+ s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/ri_cal", "component_attributes/alarm.yml", "component_attributes/calendar.yml", "component_attributes/component_property_defs.yml", "component_attributes/event.yml", "component_attributes/freebusy.yml", "component_attributes/journal.yml", "component_attributes/timezone.yml", "component_attributes/timezone_period.yml", "component_attributes/todo.yml", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt", "docs/rfc2445.pdf", "lib/ri_cal.rb", "lib/ri_cal/component.rb", "lib/ri_cal/component/alarm.rb", "lib/ri_cal/component/calendar.rb", "lib/ri_cal/component/event.rb", "lib/ri_cal/component/freebusy.rb", "lib/ri_cal/component/journal.rb", "lib/ri_cal/component/non_standard.rb", "lib/ri_cal/component/t_z_info_timezone.rb", "lib/ri_cal/component/timezone.rb", "lib/ri_cal/component/timezone/daylight_period.rb", "lib/ri_cal/component/timezone/standard_period.rb", "lib/ri_cal/component/timezone/timezone_period.rb", "lib/ri_cal/component/todo.rb", "lib/ri_cal/core_extensions.rb", "lib/ri_cal/core_extensions/array.rb", "lib/ri_cal/core_extensions/array/conversions.rb", "lib/ri_cal/core_extensions/date.rb", "lib/ri_cal/core_extensions/date/conversions.rb", "lib/ri_cal/core_extensions/date_time.rb", "lib/ri_cal/core_extensions/date_time/conversions.rb", "lib/ri_cal/core_extensions/object.rb", "lib/ri_cal/core_extensions/object/conversions.rb", "lib/ri_cal/core_extensions/string.rb", "lib/ri_cal/core_extensions/string/conversions.rb", "lib/ri_cal/core_extensions/time.rb", "lib/ri_cal/core_extensions/time/calculations.rb", "lib/ri_cal/core_extensions/time/conversions.rb", "lib/ri_cal/core_extensions/time/tzid_access.rb", "lib/ri_cal/core_extensions/time/week_day_predicates.rb", "lib/ri_cal/fast_date_time.rb", "lib/ri_cal/floating_timezone.rb", "lib/ri_cal/invalid_property_value.rb", "lib/ri_cal/invalid_timezone_identifier.rb", "lib/ri_cal/occurrence_enumerator.rb", "lib/ri_cal/occurrence_period.rb", "lib/ri_cal/parser.rb", "lib/ri_cal/properties.rb", "lib/ri_cal/properties/alarm.rb", "lib/ri_cal/properties/calendar.rb", "lib/ri_cal/properties/event.rb", "lib/ri_cal/properties/freebusy.rb", "lib/ri_cal/properties/journal.rb", "lib/ri_cal/properties/timezone.rb", "lib/ri_cal/properties/timezone_period.rb", "lib/ri_cal/properties/todo.rb", "lib/ri_cal/property_value.rb", "lib/ri_cal/property_value/array.rb", "lib/ri_cal/property_value/cal_address.rb", "lib/ri_cal/property_value/date.rb", "lib/ri_cal/property_value/date_time.rb", "lib/ri_cal/property_value/date_time/additive_methods.rb", "lib/ri_cal/property_value/date_time/time_machine.rb", "lib/ri_cal/property_value/date_time/timezone_support.rb", "lib/ri_cal/property_value/duration.rb", "lib/ri_cal/property_value/geo.rb", "lib/ri_cal/property_value/integer.rb", "lib/ri_cal/property_value/occurrence_list.rb", "lib/ri_cal/property_value/period.rb", "lib/ri_cal/property_value/recurrence_rule.rb", "lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb", "lib/ri_cal/property_value/recurrence_rule/enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb", "lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/numbered_span.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb", "lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb", "lib/ri_cal/property_value/recurrence_rule/validations.rb", "lib/ri_cal/property_value/text.rb", "lib/ri_cal/property_value/uri.rb", "lib/ri_cal/property_value/utc_offset.rb", "lib/ri_cal/required_timezones.rb", "performance/empty_propval/subject.rb", "performance/paris_eastern/subject.rb", "performance/penultimate_weekday/subject.rb", "performance/psm_big_enum/ical.ics", "performance/psm_big_enum/subject.rb", "performance/utah_cycling/subject.rb", "ri_cal.gemspec", "script/benchmark_subject", "script/console", "script/destroy", "script/generate", "script/profile_subject", "script/txt2html", "spec/ri_cal/bugreports_spec.rb", "spec/ri_cal/component/alarm_spec.rb", "spec/ri_cal/component/calendar_spec.rb", "spec/ri_cal/component/event_spec.rb", "spec/ri_cal/component/freebusy_spec.rb", "spec/ri_cal/component/journal_spec.rb", "spec/ri_cal/component/t_z_info_timezone_spec.rb", "spec/ri_cal/component/timezone_spec.rb", "spec/ri_cal/component/todo_spec.rb", "spec/ri_cal/component_spec.rb", "spec/ri_cal/core_extensions/string/conversions_spec.rb", "spec/ri_cal/core_extensions/time/calculations_spec.rb", "spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb", "spec/ri_cal/fast_date_time_spec.rb", "spec/ri_cal/occurrence_enumerator_spec.rb", "spec/ri_cal/parser_spec.rb", "spec/ri_cal/property_value/date_spec.rb", "spec/ri_cal/property_value/date_time_spec.rb", "spec/ri_cal/property_value/duration_spec.rb", "spec/ri_cal/property_value/occurrence_list_spec.rb", "spec/ri_cal/property_value/period_spec.rb", "spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb", "spec/ri_cal/property_value/recurrence_rule_spec.rb", "spec/ri_cal/property_value/text_spec.rb", "spec/ri_cal/property_value/utc_offset_spec.rb", "spec/ri_cal/property_value_spec.rb", "spec/ri_cal/required_timezones_spec.rb", "spec/ri_cal_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/gem_loader/load_active_support.rb", "tasks/gem_loader/load_tzinfo_gem.rb", "tasks/ri_cal.rake", "tasks/spec.rake"]
23
23
  s.homepage = %q{http://ri-cal.rubyforge.org/}
24
24
  s.rdoc_options = ["--main", "README.txt"]
25
25
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ri_cal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - author=Rick DeNatale
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-11 00:00:00 -04:00
12
+ date: 2009-09-18 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -118,10 +118,11 @@ files:
118
118
  - lib/ri_cal/fast_date_time.rb
119
119
  - lib/ri_cal/floating_timezone.rb
120
120
  - lib/ri_cal/invalid_property_value.rb
121
- - lib/ri_cal/invalid_timezone_identifer.rb
121
+ - lib/ri_cal/invalid_timezone_identifier.rb
122
122
  - lib/ri_cal/occurrence_enumerator.rb
123
123
  - lib/ri_cal/occurrence_period.rb
124
124
  - lib/ri_cal/parser.rb
125
+ - lib/ri_cal/properties.rb
125
126
  - lib/ri_cal/properties/alarm.rb
126
127
  - lib/ri_cal/properties/calendar.rb
127
128
  - lib/ri_cal/properties/event.rb
@@ -149,11 +150,31 @@ files:
149
150
  - lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb
150
151
  - lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb
151
152
  - lib/ri_cal/property_value/recurrence_rule/numbered_span.rb
152
- - lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb
153
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb
154
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb
155
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb
156
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb
157
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb
158
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb
159
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb
160
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb
161
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb
162
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb
163
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb
164
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb
165
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb
166
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb
167
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb
168
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb
169
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb
170
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb
171
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb
172
+ - lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb
153
173
  - lib/ri_cal/property_value/recurrence_rule/recurring_day.rb
154
174
  - lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb
155
175
  - lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb
156
176
  - lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb
177
+ - lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb
157
178
  - lib/ri_cal/property_value/recurrence_rule/validations.rb
158
179
  - lib/ri_cal/property_value/text.rb
159
180
  - lib/ri_cal/property_value/uri.rb
@@ -166,7 +187,6 @@ files:
166
187
  - performance/psm_big_enum/subject.rb
167
188
  - performance/utah_cycling/subject.rb
168
189
  - ri_cal.gemspec
169
- - sample_ical_files/from_ical_dot_app/test1.ics
170
190
  - script/benchmark_subject
171
191
  - script/console
172
192
  - script/destroy
@@ -1,793 +0,0 @@
1
- module RiCal
2
- class PropertyValue
3
- class RecurrenceRule < PropertyValue
4
- module TimeManipulation #:nodoc:
5
-
6
- def advance_day(date_time)
7
- date_time.advance(:days => 1)
8
- end
9
-
10
- def first_hour_of_day(date_time)
11
- date_time.change(:hour => 0)
12
- end
13
-
14
- def advance_week(date_time)
15
- date_time.advance(:days => 7)
16
- end
17
-
18
- def first_day_of_week(wkst_day, date_time)
19
- date_time.at_start_of_week_with_wkst(wkst_day)
20
- end
21
-
22
- def advance_month(date_time)
23
- date_time.advance(:months => 1)
24
- end
25
-
26
- def first_day_of_month(date_time)
27
- date_time.change(:day => 1)
28
- end
29
-
30
- def advance_year(date_time)
31
- date_time.advance(:years => 1)
32
- end
33
-
34
- def first_day_of_year(date_time)
35
- date_time.change(:month => 1, :day => 1)
36
- end
37
- end
38
- #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
39
- #
40
- class OccurrenceIncrementer # :nodoc:
41
-
42
- attr_accessor :sub_cycle_incrementer, :current_occurrence, :outer_range
43
- attr_accessor :outer_incrementers
44
- attr_accessor :contains_daily_incrementer, :contains_weeknum_incrementer
45
- attr_reader :leaf_iterator
46
-
47
- include TimeManipulation
48
-
49
- class NullSubCycleIncrementer #:nodoc:
50
- def self.next_time(previous)
51
- nil
52
- end
53
-
54
- def self.add_outer_incrementer(incrementer)
55
- end
56
-
57
- def self.first_within_outer_cycle(previous_occurrence, outer_cycle_range)
58
- outer_cycle_range.first
59
- end
60
-
61
- def self.first_sub_occurrence(previous_occurrence, outer_cycle_range)
62
- nil
63
- end
64
-
65
- def self.cycle_adjust(date_time)
66
- date_time
67
- end
68
-
69
- def self.to_s
70
- "NULL-INCR"
71
- end
72
-
73
- def inspect
74
- to_s
75
- end
76
- end
77
-
78
- def initialize(rrule, sub_cycle_incrementer)
79
- self.sub_cycle_incrementer = sub_cycle_incrementer
80
- @outermost = true
81
- self.outer_incrementers = []
82
- if sub_cycle_incrementer
83
- self.contains_daily_incrementer = sub_cycle_incrementer.daily_incrementer? ||
84
- sub_cycle_incrementer.contains_daily_incrementer?
85
- self.contains_weeknum_incrementer = sub_cycle_incrementer.weeknum_incrementer?||
86
- sub_cycle_incrementer.contains_weeknum_incrementer?
87
- sub_cycle_incrementer.add_outer_incrementer(self)
88
- else
89
- self.sub_cycle_incrementer = NullSubCycleIncrementer
90
- end
91
- end
92
-
93
- def add_outer_incrementer(incrementer)
94
- @outermost = false
95
- self.outer_incrementers << incrementer
96
- sub_cycle_incrementer.add_outer_incrementer(incrementer)
97
- end
98
-
99
- def outermost?
100
- @outermost
101
- end
102
-
103
- def to_s
104
- if sub_cycle_incrementer
105
- "#{self.short_name}->#{sub_cycle_incrementer}"
106
- else
107
- self.short_name
108
- end
109
- end
110
-
111
- def short_name
112
- @short_name ||= self.class.name.split("::").last
113
- end
114
-
115
- # Return the next time after previous_occurrence generated by this incrementer
116
- # But the occurrence is outside the current cycle of any outer incrementer(s) return
117
- # nil which will cause the outer incrementer to step to its next cycle.
118
- def next_time(previous_occurrence)
119
- if current_occurrence
120
- sub_occurrence = sub_cycle_incrementer.next_time(previous_occurrence)
121
- else #first time
122
- sub_occurrence = sub_cycle_incrementer.first_sub_occurrence(previous_occurrence, update_cycle_range(previous_occurrence))
123
- end
124
- if sub_occurrence
125
- candidate = sub_occurrence
126
- else
127
- candidate = next_cycle(previous_occurrence)
128
- end
129
- if in_outer_cycle?(candidate)
130
- candidate
131
- else
132
- nil
133
- end
134
- end
135
-
136
- def update_cycle_range(date_time)
137
- self.current_occurrence = date_time
138
- (date_time..end_of_occurrence(date_time))
139
- end
140
-
141
- def in_outer_cycle?(candidate)
142
- candidate && (outer_range.nil? || (outer_range.first <= candidate && outer_range.last >= candidate))
143
- end
144
-
145
- def first_sub_occurrence(previous_occurrence, outer_cycle_range)
146
- first_within_outer_cycle(previous_occurrence, outer_cycle_range)
147
- end
148
-
149
- # Advance to the next cycle, if the result is within the current cycles of all outer incrementers
150
- def next_cycle(previous_occurrence)
151
- raise "next_cycle is a subclass responsibility"
152
- end
153
-
154
- def contains_daily_incrementer?
155
- @contains_daily_incrementer
156
- end
157
-
158
- def daily_incrementer?
159
- false
160
- end
161
-
162
- def contains_weeknum_incrementer?
163
- @contains_weeknum_incrementer
164
- end
165
-
166
- def weeknum_incrementer?
167
- false
168
- end
169
- end
170
-
171
- # A ListIncrementer represents a byxxx part of a recurrence rule
172
- # It contains a list of simple values or recurring values
173
- # It keeps a collection of occurrences within a given range called a cycle
174
- # When the collection of occurrences is exhausted it is refreshed if there is no
175
- # outer incrementer, or if a new cycle would start in the current cycle of the outer incrementers.
176
- class ListIncrementer < OccurrenceIncrementer #:nodoc:
177
- attr_accessor :occurrences, :list, :outer_occurrence, :cycle_start
178
-
179
- def initialize(rrule, list, sub_cycle_incrementer)
180
- super(rrule, sub_cycle_incrementer)
181
- self.list = list
182
- end
183
-
184
- def self.conditional_incrementer(rrule, by_part, sub_cycle_class)
185
- sub_cycle_incrementer = sub_cycle_class.for_rrule(rrule)
186
- list = rrule.by_rule_list(by_part)
187
- if list
188
- new(rrule, list, sub_cycle_incrementer)
189
- else
190
- sub_cycle_incrementer
191
- end
192
- end
193
-
194
- # Advance to the next occurrence, if the result is within the current cycles of all outer incrementers
195
- def next_cycle(previous_occurrence)
196
- unless occurrences
197
- self.occurrences = occurrences_for(previous_occurrence)
198
- end
199
- candidate = next_candidate(previous_occurrence)
200
- if candidate
201
- sub_cycle_incrementer.first_within_outer_cycle(previous_occurrence, update_cycle_range(candidate))
202
- else
203
- nil
204
- end
205
- end
206
-
207
- def first_within_outer_cycle(previous_occurrence, outer_range)
208
- self.outer_range = outer_range
209
- self.occurrences = occurrences_within(outer_range)
210
- occurrences.each { |occurrence|
211
- sub = sub_cycle_incrementer.first_within_outer_cycle(previous_occurrence, update_cycle_range(occurrence))
212
- return sub if sub && sub > previous_occurrence
213
- }
214
- nil
215
- end
216
-
217
- def next_candidate(date_time)
218
- candidate = next_in_list(date_time)
219
- if outermost?
220
- while candidate.nil?
221
- get_next_occurrences
222
- candidate = next_in_list(date_time)
223
- end
224
- end
225
- candidate
226
- end
227
-
228
- def next_in_list(date_time)
229
- occurrences.find {|occurrence| occurrence > date_time}
230
- end
231
-
232
- def get_next_occurrences
233
- adv_cycle = advance_cycle(start_of_cycle(occurrences.first))
234
- self.occurrences = occurrences_for(adv_cycle)
235
- end
236
-
237
- def cycle_adjust(date_time)
238
- sub_cycle_incrementer.cycle_adjust(start_of_cycle(date_time))
239
- end
240
-
241
- def occurrences_for(date_time)
242
- list.map {|value| date_time.change(varying_time_attribute => value)}
243
- end
244
-
245
- def occurrences_within(date_time_range)
246
- result = []
247
- date_time = date_time_range.first
248
- while date_time <= date_time_range.last
249
- result << occurrences_for(date_time)
250
- date_time = advance_cycle(date_time)
251
- end
252
- result.flatten
253
- end
254
- end
255
-
256
- # A FrequenceIncrementer represents the xxxLY and FREQ parts of a recurrence rule
257
- # A FrequenceIncrementer has a single occurrence within each cycle.
258
- class FrequencyIncrementer < OccurrenceIncrementer #:nodoc:
259
- attr_accessor :interval, :outer_occurrence, :skip_increment
260
-
261
- alias_method :cycle_start, :current_occurrence
262
-
263
- def initialize(rrule, sub_cycle_incrementer)
264
- super(rrule, sub_cycle_incrementer)
265
- self.interval = rrule.interval
266
- end
267
-
268
- def self.conditional_incrementer(rrule, freq_str, sub_cycle_class)
269
- sub_cycle_incrementer = sub_cycle_class.for_rrule(rrule)
270
- if rrule.freq == freq_str
271
- new(rrule, sub_cycle_incrementer)
272
- else
273
- sub_cycle_incrementer
274
- end
275
- end
276
-
277
- def multiplier
278
- 1
279
- end
280
-
281
- def step(occurrence)
282
- occurrence.advance(advance_what => (interval * multiplier))
283
- end
284
-
285
- def first_within_outer_cycle(previous_occurrence, outer_cycle_range)
286
- if outer_range
287
- first_occurrence = outer_cycle_range.first
288
- else
289
- first_occurrence = step(previous_occurrence)
290
- end
291
- self.outer_range = outer_cycle_range
292
- sub_cycle_incrementer.first_within_outer_cycle(previous_occurrence, update_cycle_range(first_occurrence))
293
- end
294
-
295
- # Advance to the next occurrence, if the result is within the current cycles of all outer incrementers
296
- def next_cycle(previous_occurrence)
297
- if current_occurrence
298
- candidate = sub_cycle_incrementer.cycle_adjust(step(current_occurrence))
299
- else
300
- candidate = step(previous_occurrence)
301
- end
302
- if outermost?
303
- sub_occurrence = sub_cycle_incrementer.first_within_outer_cycle(previous_occurrence, update_cycle_range(candidate))
304
- until sub_occurrence
305
- candidate = sub_cycle_incrementer.cycle_adjust(step(candidate))
306
- sub_occurrence = sub_cycle_incrementer.first_within_outer_cycle(previous_occurrence, update_cycle_range(candidate))
307
- end
308
- sub_occurrence
309
- elsif in_outer_cycle?(candidate)
310
- sub_cycle_incrementer.first_within_outer_cycle(previous_occurrence, update_cycle_range(candidate))
311
- else
312
- nil
313
- end
314
- end
315
- end
316
-
317
- class SecondlyIncrementer < FrequencyIncrementer #:nodoc:
318
-
319
- def self.for_rrule(rrule)
320
- if rrule.freq == "SECONDLY"
321
- new(rrule, nil)
322
- else
323
- nil
324
- end
325
- end
326
-
327
- def advance_what
328
- :seconds
329
- end
330
-
331
- def end_of_occurrence(date_time)
332
- date_time
333
- end
334
- end
335
-
336
-
337
- class BySecondIncrementer < ListIncrementer #:nodoc:
338
-
339
- def self.for_rrule(rrule)
340
- conditional_incrementer(rrule, :bysecond, SecondlyIncrementer)
341
- end
342
-
343
- def varying_time_attribute
344
- :sec
345
- end
346
-
347
- def start_of_cycle(date_time)
348
- date_time.start_of_minute
349
- end
350
-
351
- def advance_cycle(date_time)
352
- date_time.advance(:minutes => 1).start_of_minute
353
- end
354
-
355
- def end_of_occurrence(date_time)
356
- date_time
357
- end
358
- end
359
-
360
- class MinutelyIncrementer < FrequencyIncrementer #:nodoc:
361
- def self.for_rrule(rrule)
362
- conditional_incrementer(rrule, "MINUTELY", BySecondIncrementer)
363
- end
364
-
365
- def advance_what
366
- :minutes
367
- end
368
-
369
- def end_of_occurrence(date_time)
370
- date_time.end_of_minute
371
- end
372
- end
373
-
374
- class ByMinuteIncrementer < ListIncrementer #:nodoc:
375
- def self.for_rrule(rrule)
376
- conditional_incrementer(rrule, :byminute, MinutelyIncrementer)
377
- end
378
-
379
- def advance_cycle(date_time)
380
- date_time.advance(:hours => 1).start_of_hour
381
- end
382
-
383
- def start_of_cycle(date_time)
384
- date_time.change(:min => 0)
385
- end
386
-
387
- def end_of_occurrence(date_time)
388
- date_time.end_of_minute
389
- end
390
-
391
- def varying_time_attribute
392
- :min
393
- end
394
- end
395
-
396
- class HourlyIncrementer < FrequencyIncrementer #:nodoc:
397
- def self.for_rrule(rrule)
398
- conditional_incrementer(rrule, "HOURLY", ByMinuteIncrementer)
399
- end
400
-
401
- def advance_what
402
- :hours
403
- end
404
-
405
- def end_of_occurrence(date_time)
406
- date_time.end_of_hour
407
- end
408
- end
409
-
410
- class ByHourIncrementer < ListIncrementer #:nodoc:
411
- def self.for_rrule(rrule)
412
- conditional_incrementer(rrule, :byhour, HourlyIncrementer)
413
- end
414
-
415
- def start_of_cycle(date_time)
416
- date_time.change(:hour => 0)
417
- end
418
-
419
- def varying_time_attribute
420
- :hour
421
- end
422
-
423
- def advance_cycle(date_time)
424
- first_hour_of_day(advance_day(date_time))
425
- end
426
-
427
- def end_of_occurrence(date_time)
428
- date_time.end_of_hour
429
- end
430
- end
431
-
432
- class DailyIncrementer < FrequencyIncrementer #:nodoc:
433
-
434
- def self.for_rrule(rrule)
435
- conditional_incrementer(rrule, "DAILY", ByHourIncrementer)
436
- end
437
-
438
- def daily_incrementer?
439
- true
440
- end
441
-
442
- def advance_what
443
- :days
444
- end
445
-
446
- def end_of_occurrence(date_time)
447
- date_time.end_of_day
448
- end
449
- end
450
-
451
- class ByNumberedDayIncrementer < ListIncrementer #:nodoc:
452
-
453
- def daily_incrementer?
454
- true
455
- end
456
-
457
- def occurrences_for(date_time)
458
- if occurrences && @scoping_value == scope_of(date_time)
459
- occurrences
460
- else
461
- @scoping_value = scope_of(date_time)
462
- self.occurrences = list.map {|numbered_day| numbered_day.target_date_time_for(date_time)}.uniq.sort
463
- occurrences
464
- end
465
- end
466
-
467
- def end_of_occurrence(date_time)
468
- date_time.end_of_day
469
- end
470
-
471
- def candidate_acceptible?(candidate)
472
- list.any? {|by_part| by_part.include?(candidate)}
473
- end
474
- end
475
-
476
- class ByMonthdayIncrementer < ByNumberedDayIncrementer #:nodoc:
477
- def self.for_rrule(rrule)
478
- conditional_incrementer(rrule, :bymonthday, DailyIncrementer)
479
- end
480
-
481
- def scope_of(date_time)
482
- date_time.month
483
- end
484
-
485
- def start_of_cycle(date_time)
486
- date_time.change(:day => 1)
487
- end
488
-
489
- def advance_cycle(date_time)
490
- first_day_of_month(advance_month(date_time))
491
- end
492
-
493
- def end_of_occurrence(date_time)
494
- date_time.end_of_day
495
- end
496
- end
497
-
498
- class ByYeardayIncrementer < ByNumberedDayIncrementer #:nodoc:
499
- def self.for_rrule(rrule)
500
- conditional_incrementer(rrule, :byyearday, ByMonthdayIncrementer)
501
- end
502
-
503
- def start_of_cycle(date_time)
504
- date_time.change(:month => 1, :day => 1)
505
- end
506
-
507
- def scope_of(date_time)
508
- date_time.year
509
- end
510
-
511
- def advance_cycle(date_time)
512
- first_day_of_year(advance_year(date_time))
513
- end
514
-
515
- def end_of_occurrence(date_time)
516
- date_time.end_of_day
517
- end
518
- end
519
-
520
- class ByDayIncrementer < ListIncrementer #:nodoc:
521
-
522
- def initialize(rrule, list, by_monthday_list, by_yearday_list, parent)
523
- super(rrule, list, parent)
524
- @monthday_filters = by_monthday_list
525
- @yearday_filters = by_yearday_list
526
- @by_day_scope = rrule.by_day_scope
527
-
528
- case rrule.by_day_scope
529
- when :yearly
530
- @cycle_advance_proc = lambda {|date_time| first_day_of_year(advance_year(date_time))}
531
- @current_proc = lambda {|date_time| same_year?(current, date_time)}
532
- @first_day_proc = lambda {|date_time| first_day_of_year(date_time)}
533
- when :monthly
534
- @cycle_advance_proc = lambda {|date_time| first_day_of_month(advance_month(date_time))}
535
- @current_proc = lambda {|date_time| same_month?(current, date_time)}
536
- @first_day_proc = lambda {|date_time| first_day_of_month(date_time)}
537
- when :weekly
538
- @cycle_advance_proc = lambda {|date_time| first_day_of_week(rrule.wkst_day, advance_week(date_time))}
539
- @current_proc = lambda {|date_time| same_week?(rrule.wkst_day, current, date_time)}
540
- @first_day_proc = lambda {|date_time| first_day_of_week(rrule.wkst_day, date_time)}
541
- else
542
- raise "Invalid recurrence rule, byday needs to be scoped by month, week or year"
543
- end
544
- end
545
-
546
- def self.for_rrule(rrule)
547
- list = rrule.by_rule_list(:byday)
548
- if list
549
- sub_cycle_incrementer = DailyIncrementer.for_rrule(rrule)
550
- new(rrule, list, rrule.by_rule_list(:bymonthday), rrule.by_rule_list(:byyearday), sub_cycle_incrementer)
551
- else
552
- ByYeardayIncrementer.for_rrule(rrule)
553
- end
554
- end
555
-
556
- def daily_incrementer?
557
- true
558
- end
559
-
560
- def start_of_cycle(date_time)
561
- @first_day_proc.call(date_time)
562
- end
563
-
564
- def occurrences_for(date_time)
565
- first_day = start_of_cycle(date_time)
566
- result = list.map {|recurring_day| recurring_day.matches_for(first_day)}.flatten.uniq.sort
567
- if @monthday_filters
568
- result = result.select {|occurrence| @monthday_filters.any? {|recurring_day| recurring_day.include?(occurrence)}}
569
- end
570
- if @yearday_filters
571
- result = result.select {|occurrence| @yearday_filters.any? {|recurring_day| recurring_day.include?(occurrence)}}
572
- end
573
- result
574
- end
575
-
576
- def candidate_acceptible?(candidate)
577
- list.any? {|recurring_day| recurring_day.include?(candidate)}
578
- end
579
-
580
- def varying_time_attribute
581
- :day
582
- end
583
-
584
- def advance_cycle(date_time)
585
- @cycle_advance_proc.call(date_time)
586
- end
587
-
588
- def end_of_occurrence(date_time)
589
- date_time.end_of_day
590
- end
591
- end
592
-
593
- class WeeklyIncrementer < FrequencyIncrementer #:nodoc:
594
-
595
- attr_reader :wkst
596
-
597
- # include WeeklyBydayMethods
598
-
599
- def initialize(rrule, parent)
600
- @wkst = rrule.wkst_day
601
- super(rrule, parent)
602
- end
603
-
604
- def self.for_rrule(rrule)
605
- conditional_incrementer(rrule, "WEEKLY", ByDayIncrementer)
606
- end
607
-
608
- def multiplier
609
- 7
610
- end
611
-
612
- def advance_what
613
- :days
614
- end
615
-
616
- def end_of_occurrence(date_time)
617
- date_time.end_of_week_with_wkst(wkst)
618
- end
619
- end
620
-
621
- class ByWeekNoIncrementer < ListIncrementer #:nodoc:
622
- attr_reader :wkst
623
- # include WeeklyBydayMethods
624
-
625
- def initialize(rrule, list, sub_cycle_incrementer)
626
- @wkst = rrule.wkst_day
627
- super(rrule, list, sub_cycle_incrementer)
628
- end
629
-
630
- def self.for_rrule(rrule)
631
- conditional_incrementer(rrule, :byweekno, WeeklyIncrementer)
632
- end
633
-
634
- def weeknum_incrementer?
635
- true
636
- end
637
-
638
- def first_within_outer_cycle(previous_occurrence, outer_range)
639
- new_range_start = outer_range.first
640
- new_range_end = new_range_start.end_of_iso_year(wkst)
641
- super(previous_occurrence, outer_range.first..new_range_end)
642
- end
643
-
644
- def start_of_cycle(date_time)
645
- result = date_time.at_start_of_iso_year(wkst)
646
- result
647
- end
648
-
649
- def occurrences_for(date_time)
650
- iso_year, year_start = *date_time.iso_year_and_week_one_start(wkst)
651
- week_one_occurrence = date_time.change(
652
- :year => year_start.year,
653
- :month => year_start.month,
654
- :day => year_start.day
655
- )
656
- weeks_in_year_plus_one = week_one_occurrence.iso_weeks_in_year(wkst)
657
- weeks = list.map {|recurring_weeknum|
658
- wk_num = recurring_weeknum.ordinal
659
- (wk_num > 0) ? wk_num : weeks_in_year_plus_one + wk_num
660
- }.uniq.sort
661
- weeks.map {|wk_num| week_one_occurrence.advance(:days => (wk_num - 1) * 7)}
662
- end
663
-
664
- def candidate_acceptible?(candidate)
665
- list.include?(candidate.iso_week_num(wkst))
666
- end
667
-
668
- def advance_cycle(date_time)
669
- date_time.at_start_of_next_iso_year(wkst)
670
- end
671
-
672
- def end_of_occurrence(date_time)
673
- date_time.end_of_week_with_wkst(wkst)
674
- end
675
- end
676
-
677
- class MonthlyIncrementer < FrequencyIncrementer #:nodoc:
678
-
679
- def self.for_rrule(rrule)
680
- conditional_incrementer(rrule, "MONTHLY", ByWeekNoIncrementer)
681
- end
682
-
683
- def advance_what
684
- :months
685
- end
686
-
687
- def step(date_time)
688
- if contains_daily_incrementer?
689
- result = super(date_time).change(:day => 1)
690
- result
691
- else
692
- super(date_time)
693
- end
694
- end
695
-
696
- def end_of_occurrence(date_time)
697
- date_time.end_of_month
698
- end
699
- end
700
-
701
- class ByMonthIncrementer < ListIncrementer #:nodoc:
702
-
703
- def self.for_rrule(rrule)
704
- conditional_incrementer(rrule, :bymonth, MonthlyIncrementer)
705
- end
706
-
707
- def occurrences_for(date_time)
708
- if contains_daily_incrementer?
709
- list.map {|value| date_time.change(:month => value, :day => 1)}
710
- else
711
- list.map {|value| date_time.in_month(value)}
712
- end
713
- end
714
-
715
- def range_advance(date_time)
716
- advance_year(date_time)
717
- end
718
-
719
- def start_of_cycle(date_time)
720
- if contains_daily_incrementer?
721
- date_time.change(:month => 1, :day => 1)
722
- else
723
- date_time.change(:month => 1)
724
- end
725
- end
726
-
727
- def varying_time_attribute
728
- :month
729
- end
730
-
731
- def advance_cycle(date_time)
732
- if contains_daily_incrementer?
733
- first_day_of_year(advance_year(date_time))
734
- else
735
- advance_year(date_time).change(:month => 1)
736
- end
737
- end
738
-
739
- def end_of_occurrence(date_time)
740
- date_time.end_of_month
741
- end
742
- end
743
-
744
- class YearlyIncrementer < FrequencyIncrementer #:nodoc:
745
-
746
- attr_reader :wkst
747
-
748
- def initialize(rrule, sub_cycle_incrementer)
749
- @wkst = rrule.wkst_day
750
- super(rrule, sub_cycle_incrementer)
751
- end
752
-
753
- def self.from_rrule(rrule, start_time)
754
- conditional_incrementer(rrule, "YEARLY", ByMonthIncrementer)
755
- end
756
-
757
- def advance_what
758
- :years
759
- end
760
-
761
- def step(date_time)
762
- if contains_weeknum_incrementer?
763
- result = date_time
764
- multiplier.times do
765
- result = result.at_start_of_next_iso_year(wkst)
766
- end
767
- result
768
- else
769
- super(date_time)
770
- end
771
- end
772
-
773
- def start_of_cycle(date_time)
774
- if contains_weeknum_incrementer?
775
- date_time.at_start_of_iso_year(wkst)
776
- elsif contains_daily_incrementer?
777
- date_time.change(:month => 1, :day => 1)
778
- else
779
- date_time.change(:month => 1)
780
- end
781
- end
782
-
783
- def end_of_occurrence(date_time)
784
- if contains_weeknum_incrementer?
785
- date_time.end_of_iso_year(wkst)
786
- else
787
- date_time.end_of_year
788
- end
789
- end
790
- end
791
- end
792
- end
793
- end