mhc 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/COPYRIGHT +28 -0
- data/Gemfile +8 -0
- data/README.org +209 -0
- data/Rakefile +13 -0
- data/bin/mhc +312 -0
- data/emacs/Cask +25 -0
- data/emacs/Makefile +58 -0
- data/emacs/mhc-calendar.el +1723 -0
- data/emacs/mhc-calfw.el +135 -0
- data/emacs/mhc-compat.el +90 -0
- data/emacs/mhc-date.el +642 -0
- data/emacs/mhc-day.el +149 -0
- data/emacs/mhc-db.el +158 -0
- data/emacs/mhc-draft.el +211 -0
- data/emacs/mhc-e21.el +167 -0
- data/emacs/mhc-face.el +236 -0
- data/emacs/mhc-file.el +224 -0
- data/emacs/mhc-guess.el +648 -0
- data/emacs/mhc-header.el +176 -0
- data/emacs/mhc-logic.el +563 -0
- data/emacs/mhc-message.el +130 -0
- data/emacs/mhc-minibuf.el +466 -0
- data/emacs/mhc-misc.el +248 -0
- data/emacs/mhc-mua.el +260 -0
- data/emacs/mhc-parse.el +286 -0
- data/emacs/mhc-process.el +35 -0
- data/emacs/mhc-ps.el +1174 -0
- data/emacs/mhc-record.el +201 -0
- data/emacs/mhc-schedule.el +202 -0
- data/emacs/mhc-summary.el +763 -0
- data/emacs/mhc-sync.el +158 -0
- data/emacs/mhc-vars.el +149 -0
- data/emacs/mhc.el +1114 -0
- data/icons/Anniversary.xbm +6 -0
- data/icons/Anniversary.xpm +27 -0
- data/icons/Birthday.xbm +6 -0
- data/icons/Birthday.xpm +25 -0
- data/icons/Business.xbm +6 -0
- data/icons/Business.xpm +24 -0
- data/icons/CheckBox.xbm +6 -0
- data/icons/CheckBox.xpm +24 -0
- data/icons/CheckedBox.xbm +6 -0
- data/icons/CheckedBox.xpm +25 -0
- data/icons/Conflict.xbm +6 -0
- data/icons/Conflict.xpm +22 -0
- data/icons/Date.xbm +6 -0
- data/icons/Date.xpm +29 -0
- data/icons/Holiday.xbm +6 -0
- data/icons/Holiday.xpm +25 -0
- data/icons/Link.xbm +6 -0
- data/icons/Link.xpm +25 -0
- data/icons/Other.xbm +6 -0
- data/icons/Other.xpm +28 -0
- data/icons/Party.xbm +6 -0
- data/icons/Party.xpm +23 -0
- data/icons/Private.xbm +6 -0
- data/icons/Private.xpm +26 -0
- data/icons/Recurrence.xbm +6 -0
- data/icons/Recurrence.xpm +98 -0
- data/icons/Vacation.xbm +6 -0
- data/icons/Vacation.xpm +26 -0
- data/lib/mhc.rb +45 -0
- data/lib/mhc/builder.rb +64 -0
- data/lib/mhc/caldav.rb +304 -0
- data/lib/mhc/calendar.rb +106 -0
- data/lib/mhc/command.rb +13 -0
- data/lib/mhc/command/cache.rb +14 -0
- data/lib/mhc/command/completions.rb +108 -0
- data/lib/mhc/command/init.rb +133 -0
- data/lib/mhc/command/scan.rb +33 -0
- data/lib/mhc/command/sync.rb +22 -0
- data/lib/mhc/config.rb +229 -0
- data/lib/mhc/converter.rb +330 -0
- data/lib/mhc/datastore.rb +164 -0
- data/lib/mhc/date_enumerator.rb +274 -0
- data/lib/mhc/date_frame.rb +124 -0
- data/lib/mhc/date_helper.rb +49 -0
- data/lib/mhc/etag.rb +68 -0
- data/lib/mhc/event.rb +396 -0
- data/lib/mhc/formatter.rb +312 -0
- data/lib/mhc/logger.rb +94 -0
- data/lib/mhc/modifier.rb +149 -0
- data/lib/mhc/occurrence.rb +94 -0
- data/lib/mhc/occurrence_enumerator.rb +113 -0
- data/lib/mhc/property_value.rb +33 -0
- data/lib/mhc/property_value/date.rb +190 -0
- data/lib/mhc/property_value/integer.rb +15 -0
- data/lib/mhc/property_value/list.rb +41 -0
- data/lib/mhc/property_value/period.rb +49 -0
- data/lib/mhc/property_value/range.rb +100 -0
- data/lib/mhc/property_value/recurrence_condition.rb +272 -0
- data/lib/mhc/property_value/text.rb +11 -0
- data/lib/mhc/property_value/time.rb +45 -0
- data/lib/mhc/query.rb +210 -0
- data/lib/mhc/sync.rb +46 -0
- data/lib/mhc/sync/driver.rb +108 -0
- data/lib/mhc/sync/status.rb +70 -0
- data/lib/mhc/sync/status_manager.rb +142 -0
- data/lib/mhc/sync/strategy.rb +233 -0
- data/lib/mhc/sync/syncinfo.rb +98 -0
- data/lib/mhc/templates/config.yml.erb +142 -0
- data/lib/mhc/version.rb +4 -0
- data/lib/mhc/webdav.rb +319 -0
- data/mhc.gemspec +24 -0
- data/samples/DOT.mhc-config.yml +116 -0
- data/samples/japanese-holidays.mhcc +153 -0
- data/samples/mhc-completions.zsh +11 -0
- data/spec/mhc_spec.rb +682 -0
- data/spec/spec_helper.rb +9 -0
- data/xpm/close.xpm +18 -0
- data/xpm/delete.xpm +19 -0
- data/xpm/exit.xpm +18 -0
- data/xpm/month.xpm +18 -0
- data/xpm/next.xpm +18 -0
- data/xpm/next2.xpm +18 -0
- data/xpm/next_year.xpm +18 -0
- data/xpm/open.xpm +19 -0
- data/xpm/prev.xpm +18 -0
- data/xpm/prev2.xpm +18 -0
- data/xpm/prev_year.xpm +18 -0
- data/xpm/save.xpm +19 -0
- data/xpm/today.xpm +18 -0
- metadata +214 -0
data/lib/mhc/logger.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
module Mhc
|
2
|
+
################################################################
|
3
|
+
# Log maintenance functions.
|
4
|
+
#
|
5
|
+
# M 2000-04-25 00:06:08 <20.nom@.nomcom> ~nom/Mail/schedule/2000/04/1 Luncheon
|
6
|
+
# D 2000-04-25 00:06:08 <20.nom@.nomcom> ~nom/Mail/schedule/2000/04/1 Luncheon
|
7
|
+
# S 2000-04-25 00:06:08 user_id
|
8
|
+
#
|
9
|
+
class Logger
|
10
|
+
def initialize(filename)
|
11
|
+
@filename = filename
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_entry(entry)
|
15
|
+
file = File.open(@filename, "a+")
|
16
|
+
file.print "#{entry}\n"
|
17
|
+
file.fsync if file.respond_to?("fsync")
|
18
|
+
file.close
|
19
|
+
end
|
20
|
+
|
21
|
+
def each_entry
|
22
|
+
begin
|
23
|
+
file = File.open(@filename)
|
24
|
+
while line = file.gets
|
25
|
+
yield(LogEntry.new(line.chomp))
|
26
|
+
end
|
27
|
+
file.close
|
28
|
+
rescue
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def entries()
|
33
|
+
arry = []
|
34
|
+
each_entry{|e|
|
35
|
+
arry << e
|
36
|
+
}
|
37
|
+
return arry
|
38
|
+
end
|
39
|
+
|
40
|
+
def shrink_entries(user_id)
|
41
|
+
hash = {}
|
42
|
+
each_entry{|e|
|
43
|
+
if e.status == 'S' and e.rec_id == user_id
|
44
|
+
hash.clear
|
45
|
+
else
|
46
|
+
hash[e.rec_id] = e
|
47
|
+
end
|
48
|
+
}
|
49
|
+
return hash.values
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class LogEntry
|
54
|
+
attr :status
|
55
|
+
attr :mtime
|
56
|
+
attr :rec_id
|
57
|
+
attr :path
|
58
|
+
attr :subject
|
59
|
+
|
60
|
+
def initialize(status, mtime = nil, rec_id = nil, path = nil, subject = nil)
|
61
|
+
if mtime.nil?
|
62
|
+
init_from_string(status)
|
63
|
+
else
|
64
|
+
@status, @mtime, @rec_id, @path, @subject =
|
65
|
+
status, mtime, rec_id, path, subject
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
return [
|
71
|
+
@status,
|
72
|
+
@mtime.strftime("%Y-%m-%d %H:%M:%S"),
|
73
|
+
@rec_id,
|
74
|
+
@path,
|
75
|
+
@subject
|
76
|
+
].join(' ')
|
77
|
+
end
|
78
|
+
|
79
|
+
################
|
80
|
+
private
|
81
|
+
################
|
82
|
+
def init_from_string(line)
|
83
|
+
str = line.chomp
|
84
|
+
status, yymmdd, hhmmss, rec_id, path, subject = str.split
|
85
|
+
yy, mm, dd = yymmdd.split('-')
|
86
|
+
h, m, s = hhmmss.split(':')
|
87
|
+
|
88
|
+
mtime = Time.local(yy.to_i, mm.to_i, dd.to_i,
|
89
|
+
h .to_i, m .to_i, s .to_i)
|
90
|
+
@status, @mtime, @rec_id, @path, @subject =
|
91
|
+
status, mtime, rec_id, path, subject
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/mhc/modifier.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
module Mhc
|
2
|
+
class Modifier
|
3
|
+
class ParseError < StandardError; end
|
4
|
+
|
5
|
+
attr_accessor :name
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
@name.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def decorate(event)
|
16
|
+
if deco = Decorator.find_subclass(@name.to_sym)
|
17
|
+
deco.new(event)
|
18
|
+
else
|
19
|
+
raise Mhc::Modifier::ParseError, "Unknown Decorator #{@name}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Decorator
|
24
|
+
require 'forwardable'
|
25
|
+
extend Forwardable
|
26
|
+
|
27
|
+
def_delegators :@event,
|
28
|
+
:path,
|
29
|
+
:alarm,
|
30
|
+
:categories,
|
31
|
+
:description,
|
32
|
+
:body,
|
33
|
+
:location,
|
34
|
+
:priority,
|
35
|
+
:record_id,
|
36
|
+
:occurrences,
|
37
|
+
:uid,
|
38
|
+
:subject,
|
39
|
+
:dates,
|
40
|
+
:exceptions,
|
41
|
+
:time_range,
|
42
|
+
:duration,
|
43
|
+
:recurrence_condition,
|
44
|
+
:recurrence_tag,
|
45
|
+
:mission_tag,
|
46
|
+
:sequence,
|
47
|
+
# :occurrences,
|
48
|
+
:dtstart,
|
49
|
+
:dtend,
|
50
|
+
:rdates,
|
51
|
+
:exdates,
|
52
|
+
:etag,
|
53
|
+
:recurring?,
|
54
|
+
:allday?
|
55
|
+
|
56
|
+
def self.find_subclass(snake_name)
|
57
|
+
@subclasses ||= {}
|
58
|
+
|
59
|
+
if c = @subclasses[snake_name]
|
60
|
+
return c
|
61
|
+
end
|
62
|
+
|
63
|
+
class_name = snake_name.to_s.capitalize.gsub(/_([a-z\d]+)/){ $1.capitalize }.to_sym
|
64
|
+
return nil unless const_defined?(class_name)
|
65
|
+
|
66
|
+
const = const_get(class_name)
|
67
|
+
if const.class == Class and const.superclass == self
|
68
|
+
return @subclasses[snake_name] = const
|
69
|
+
end
|
70
|
+
return nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def initialize(event)
|
74
|
+
@event = event
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_ics
|
78
|
+
Mhc::Converter::Icalendar.new.to_ics(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_icalendar
|
82
|
+
Mhc::Converter::Icalendar.new.to_icalendar(self)
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_ics_string
|
86
|
+
Mhc::Converter::Icalendar.new.to_ics_string(self)
|
87
|
+
end
|
88
|
+
|
89
|
+
def occurrences(range:nil)
|
90
|
+
Mhc::OccurrenceEnumerator.new(self, dates, exceptions, recurrence_condition, duration, range)
|
91
|
+
end
|
92
|
+
|
93
|
+
class HideDetails < Decorator
|
94
|
+
def subject
|
95
|
+
return Mhc::PropertyValue::Text.new.parse("BUSY")
|
96
|
+
end
|
97
|
+
|
98
|
+
def location
|
99
|
+
return nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def description
|
103
|
+
return nil
|
104
|
+
end
|
105
|
+
alias_method :body, :description
|
106
|
+
|
107
|
+
end # class HideDetails
|
108
|
+
|
109
|
+
|
110
|
+
class HideDescription < Decorator
|
111
|
+
|
112
|
+
def description
|
113
|
+
return nil
|
114
|
+
end
|
115
|
+
|
116
|
+
alias_method :body, :description
|
117
|
+
|
118
|
+
end # class HideDescription
|
119
|
+
|
120
|
+
|
121
|
+
class HideLocation < Decorator
|
122
|
+
def location
|
123
|
+
return nil
|
124
|
+
end
|
125
|
+
end # class HideLocation
|
126
|
+
|
127
|
+
|
128
|
+
class HideTimeRange < Decorator
|
129
|
+
def allday?
|
130
|
+
return true
|
131
|
+
end
|
132
|
+
|
133
|
+
def time_range
|
134
|
+
# create empty time_range
|
135
|
+
Mhc::PropertyValue::Range.new(Mhc::PropertyValue::Time)
|
136
|
+
end
|
137
|
+
end # class HideTimeRange
|
138
|
+
|
139
|
+
class ReplaceSubjectByCategory < Decorator
|
140
|
+
def subject
|
141
|
+
categories = @event.categories
|
142
|
+
return "BUSY" if categories.empty?
|
143
|
+
return categories.first.to_s.capitalize
|
144
|
+
end
|
145
|
+
end # class ReplaceSubjectByCategory
|
146
|
+
|
147
|
+
end # class Decorator
|
148
|
+
end # class Modifier
|
149
|
+
end # module Mhc
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Mhc
|
4
|
+
class Occurrence
|
5
|
+
include Comparable
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@event,
|
9
|
+
:path,
|
10
|
+
:alarm,
|
11
|
+
:categories,
|
12
|
+
:description,
|
13
|
+
:body,
|
14
|
+
:location,
|
15
|
+
:priority,
|
16
|
+
:record_id,
|
17
|
+
:uid,
|
18
|
+
:subject,
|
19
|
+
:time_range,
|
20
|
+
:recurrence_tag,
|
21
|
+
:mission_tag,
|
22
|
+
:allday?
|
23
|
+
|
24
|
+
attr_reader :event
|
25
|
+
|
26
|
+
def initialize(event, date_range)
|
27
|
+
@event = event
|
28
|
+
|
29
|
+
if date_range.respond_to?(:first)
|
30
|
+
@start_date = date_range.first
|
31
|
+
@end_date = date_range.last
|
32
|
+
else
|
33
|
+
@start_date = date_range
|
34
|
+
@end_date = date_range
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def date
|
39
|
+
@start_date
|
40
|
+
end
|
41
|
+
|
42
|
+
def dtstart
|
43
|
+
if allday?
|
44
|
+
@start_date
|
45
|
+
else
|
46
|
+
time_range.first.to_datetime(@start_date)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def dtend
|
51
|
+
if allday?
|
52
|
+
@end_date + 1
|
53
|
+
else
|
54
|
+
time_range.last.to_datetime(@end_date)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def first
|
59
|
+
@start_date
|
60
|
+
end
|
61
|
+
|
62
|
+
def last
|
63
|
+
@end_date
|
64
|
+
end
|
65
|
+
|
66
|
+
def days
|
67
|
+
@end_date - @start_date + 1
|
68
|
+
end
|
69
|
+
|
70
|
+
def oneday?
|
71
|
+
@start_date == @end_date
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_mhc_string
|
75
|
+
if allday?
|
76
|
+
return "#{dtstart.to_mhc_string}" if oneday?
|
77
|
+
return "#{@start_date.to_mhc_string}-#{@end_date.to_mhc_string}"
|
78
|
+
else
|
79
|
+
return dtstart.strftime("%Y%m%d %H:%m-") + ((@start_date == @end_date) ? dtend.strftime("%H:%m") : dtend.strftime("%Y%m%dT%H:%m"))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :to_s, :to_mhc_string
|
84
|
+
|
85
|
+
def <=>(o)
|
86
|
+
if o.respond_to?(:dtstart)
|
87
|
+
return self.dtstart <=> o.dtstart
|
88
|
+
else
|
89
|
+
return self.dtstart <=> o
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end # class Occurrence
|
94
|
+
end # module Mhc
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Mhc
|
2
|
+
class OccurrenceEnumerator
|
3
|
+
include Enumerable
|
4
|
+
# ; The FREQ rule part is REQUIRED,
|
5
|
+
# ; but MUST NOT occur more than once.
|
6
|
+
#
|
7
|
+
# FREQ = (DAILY|WEEKLY|MONTHLY|YEARLY)
|
8
|
+
#
|
9
|
+
# ; The UNTIL or COUNT rule parts are OPTIONAL,
|
10
|
+
# ; but they MUST NOT occur in the same 'recur'.
|
11
|
+
#
|
12
|
+
# UNTIL = (date|date-time)
|
13
|
+
# COUNT = \d+
|
14
|
+
#
|
15
|
+
# ; The other rule parts are OPTIONAL,
|
16
|
+
# ; but MUST NOT occur more than once.
|
17
|
+
#
|
18
|
+
# INTERVAL = \d+ # positive value default is 1
|
19
|
+
# BYDAY = ([+-]\d{1,2})?(SU|MO|TU|WE|TH|FR|SA),... # 1 to 53
|
20
|
+
# BYMONTHDAY = [+-]\d{1,2},... # 1 to 31
|
21
|
+
# BYYEARDAY = [+-]\d{1,3},... # 1 to 366
|
22
|
+
# BYWEEKNO = [+-]\d{1,3},... # 1 to 53
|
23
|
+
# BYMONTH = \d{1,2},... # 1 to 12
|
24
|
+
# BYSETPOS = [+-]\d+,... # 1 to 366
|
25
|
+
# WKST = (SU|MO|TU|WE|TH|FR|SA)
|
26
|
+
#
|
27
|
+
def initialize(event, dates, exceptions, recurrence_condition, duration, date_range = nil)
|
28
|
+
@event = event
|
29
|
+
|
30
|
+
# Since some articles with RECURRENCE_CONDITION and without DURATION
|
31
|
+
# makes infinit entries, we have to clip the range by some artificial values
|
32
|
+
# It will make 101 enum entries from 1970-1-1 to now+50 years:
|
33
|
+
#
|
34
|
+
# X-SC-Subject: New Year's Day
|
35
|
+
# X-SC-Cond: Jan 1
|
36
|
+
#
|
37
|
+
date_range = (Date.new(1970, 1, 1) .. Date.new(Date.today.year + 50)) unless date_range
|
38
|
+
|
39
|
+
# If we have both DURATION and RANGE, we can take narrower term
|
40
|
+
# by the combination of the both.
|
41
|
+
date_range = duration.narrow(date_range.first, date_range.last)
|
42
|
+
|
43
|
+
# range.last is effective in narrowing the end_date,
|
44
|
+
# however, we can't adopt range.first to the start_date.
|
45
|
+
# Original start_date derived from DURATION is required for calculating
|
46
|
+
# the start point of recurrence loop in case the
|
47
|
+
# loop interval is larger than one.
|
48
|
+
#
|
49
|
+
# At moment, we will have over-scanning entries even if the range.first
|
50
|
+
# is set narrower than duration.first
|
51
|
+
#
|
52
|
+
# we need some good way to pass the both duration.first and range.first
|
53
|
+
# to the down-stream enumerators.
|
54
|
+
#
|
55
|
+
end_date = date_range.last
|
56
|
+
start_date = duration.first || date_range.first
|
57
|
+
|
58
|
+
@enumerator = Mhc::DateEnumerator.new(start_date: start_date, end_date: date_range.last)
|
59
|
+
condition_to_enumerator(@enumerator, recurrence_condition, start_date, date_range.last)
|
60
|
+
@enumerator.add_by_range_list(range_list: dates)
|
61
|
+
@exceptions = exceptions.map{|range| range.to_a }.flatten
|
62
|
+
@date_range = date_range
|
63
|
+
end
|
64
|
+
|
65
|
+
def each
|
66
|
+
@enumerator.each do |date_or_range|
|
67
|
+
if date_or_range.respond_to?(:first)
|
68
|
+
first_date = date_or_range.first
|
69
|
+
last_date = date_or_range.last
|
70
|
+
else
|
71
|
+
first_date = date_or_range
|
72
|
+
last_date = date_or_range
|
73
|
+
end
|
74
|
+
if last_date < @date_range.first or @date_range.last < first_date
|
75
|
+
next
|
76
|
+
end
|
77
|
+
next if @exceptions.include?(first_date)
|
78
|
+
yield Mhc::Occurrence.new(@event, date_or_range)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def condition_to_enumerator(enumerator, cond, start_date, end_date)
|
85
|
+
if cond.yearly?
|
86
|
+
cond.cond_mon.each do |mon|
|
87
|
+
cond.cond_ord.each do |ord|
|
88
|
+
cond.cond_wek.each do |wek|
|
89
|
+
enumerator.add_yearly_by_day(month: mon, nth: ord, wday: wek)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
cond.cond_num.each do |num|
|
93
|
+
enumerator.add_yearly_by_monthday(month: mon, mday: num)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
elsif cond.monthly?
|
97
|
+
cond.cond_ord.each do |ord|
|
98
|
+
cond.cond_wek.each do |wek|
|
99
|
+
enumerator.add_monthly_by_day(nth: ord, wday: wek)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
cond.cond_num.each do |num|
|
103
|
+
enumerator.add_monthly_by_monthday(mday: num)
|
104
|
+
end
|
105
|
+
elsif cond.weekly?
|
106
|
+
cond.cond_wek.each do |wek|
|
107
|
+
enumerator.add_weekly(wday: wek)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
return enumerator
|
111
|
+
end
|
112
|
+
end # class OccurrenceEnumerator
|
113
|
+
end # module Mhc
|