ri_cal 0.8.2 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
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