icalPal 2.1.0 → 2.2.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 +4 -4
- data/bin/icalPal +12 -0
- data/lib/defaults.rb +1 -0
- data/lib/event.rb +85 -63
- data/lib/icalPal.rb +2 -2
- data/lib/options.rb +4 -1
- data/lib/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76513daaf66f3c4aa8b2a9e1703f275ba5d5a65ef9e8b71a86b263c59d409fdd
|
4
|
+
data.tar.gz: c06430cfbdd5c415dae2d154b774c1ba1feb210534e6511f9fbb1cf12052cbfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 290f75e744ea88673f474c478565ec281a2b8eae8dcfc730ccb7abf88f33b5fdc8c10baf53b971c336d48a3a4abc3f311e02973e9f2295fea2d134e3d987a499
|
7
|
+
data.tar.gz: af3d7eec48d408f2c7ff15af7cdddcf581fa60574e1ab3602efb32e6625bfa61833919194108fe012fbae35a312c14af6ffbf628be4921d7cd11651e67717151
|
data/bin/icalPal
CHANGED
@@ -130,6 +130,18 @@ $rows.each_with_index do |row, i|
|
|
130
130
|
next
|
131
131
|
end
|
132
132
|
|
133
|
+
# --regexp
|
134
|
+
if $opts[:match]
|
135
|
+
r = $opts[:match].split('=')
|
136
|
+
|
137
|
+
if item[r[0]].to_s.respond_to?(:match)
|
138
|
+
unless item[r[0]].to_s.match(Regexp.new(r[1].to_s, Regexp::IGNORECASE)) then
|
139
|
+
$log.debug(":regex")
|
140
|
+
next
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
133
145
|
if ICalPal::Event === item
|
134
146
|
# Check for all-day and cancelled events
|
135
147
|
if $opts[:ea] && item['all_day'].positive? then
|
data/lib/defaults.rb
CHANGED
data/lib/event.rb
CHANGED
@@ -110,20 +110,22 @@ module ICalPal
|
|
110
110
|
# If an event spans multiple days, the return value will contain
|
111
111
|
# a unique {Event} for each day that falls within our window
|
112
112
|
def non_recurring
|
113
|
-
|
113
|
+
events = []
|
114
114
|
|
115
115
|
# Repeat for multi-day events
|
116
116
|
((self['duration'] / 86400).to_i + 1).times do |i|
|
117
117
|
break if self['sdate'] > $opts[:to]
|
118
118
|
|
119
119
|
$log.debug("multi-day event #{i + 1}") if (i > 0)
|
120
|
+
|
120
121
|
self['daynum'] = i + 1
|
121
|
-
|
122
|
+
events.push(clone) if in_window?(self['sdate'])
|
123
|
+
|
122
124
|
self['sdate'] += 1
|
123
125
|
self['edate'] += 1
|
124
126
|
end
|
125
127
|
|
126
|
-
|
128
|
+
events
|
127
129
|
end
|
128
130
|
|
129
131
|
# Check recurring events
|
@@ -131,35 +133,49 @@ module ICalPal
|
|
131
133
|
# @return [Array<Event>]
|
132
134
|
# All occurrences of a recurring event that are within our window
|
133
135
|
def recurring
|
134
|
-
|
136
|
+
stop = [ $opts[:to], (self['rdate'] || $opts[:to]) ].min
|
135
137
|
|
136
138
|
# See if event ends before we start
|
137
|
-
stop = [ $opts[:to], (self['rdate'] || $opts[:to]) ].min
|
138
139
|
if stop < $opts[:from] then
|
139
140
|
$log.debug("#{stop} < #{$opts[:from]}")
|
140
|
-
return(
|
141
|
+
return(Array.new)
|
141
142
|
end
|
142
143
|
|
143
144
|
# Get changes to series
|
144
|
-
changes =
|
145
|
+
changes = [ { 'orig_date' => -1 } ]
|
146
|
+
changes += $rows.select { |r| r['orig_item_id'] == self['ROWID'] }
|
147
|
+
|
148
|
+
events = []
|
149
|
+
count = 1
|
145
150
|
|
146
|
-
i = 1
|
147
151
|
while self['sdate'] <= stop
|
148
|
-
|
149
|
-
|
150
|
-
|
152
|
+
# count
|
153
|
+
break if self['count'].positive? and count > self['count']
|
154
|
+
count += 1
|
155
|
+
|
156
|
+
# Handle specifier or clone self
|
157
|
+
if self['specifier'] and self['specifier'].length.positive?
|
158
|
+
occurrences = get_occurrences(changes)
|
159
|
+
else
|
160
|
+
occurrences = [ clone ]
|
151
161
|
end
|
152
|
-
i += 1
|
153
162
|
|
154
|
-
|
155
|
-
|
156
|
-
|
163
|
+
# Check for changes
|
164
|
+
occurrences.each do |occurrence|
|
165
|
+
changes.each do |change|
|
166
|
+
next if change['orig_date'] == self['sdate'].to_i - ITIME
|
167
|
+
events.push(occurrence) if in_window?(occurrence['sdate'], occurrence['edate'])
|
168
|
+
end
|
157
169
|
end
|
158
170
|
|
171
|
+
break if self['specifier']
|
159
172
|
apply_frequency!
|
160
173
|
end
|
161
174
|
|
162
|
-
|
175
|
+
# Remove exceptions
|
176
|
+
events.delete_if { |event| event['xdate'].any?(event['sdate']) }
|
177
|
+
|
178
|
+
return(events)
|
163
179
|
end
|
164
180
|
|
165
181
|
private
|
@@ -168,67 +184,72 @@ module ICalPal
|
|
168
184
|
|
169
185
|
# @return a deep clone of self
|
170
186
|
def clone()
|
171
|
-
self['stime'] = @self['sdate'].to_i
|
172
|
-
self['etime'] = @self['edate'].to_i
|
173
|
-
|
174
187
|
Marshal.load(Marshal.dump(self))
|
175
188
|
end
|
176
189
|
|
177
|
-
# Get next occurences of a recurring event
|
190
|
+
# Get next occurences of a recurring event from a specifier
|
178
191
|
#
|
179
192
|
# @param changes [Array] Recurrence changes for the event
|
180
193
|
# @return [Array<IcalPal::Event>]
|
181
194
|
def get_occurrences(changes)
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
195
|
+
occurrences = []
|
196
|
+
|
197
|
+
dow = DOW.keys
|
198
|
+
dom = [ nil ]
|
199
|
+
moy = 1..12
|
200
|
+
nth = nil
|
201
|
+
|
202
|
+
specifier = self['specifier']? self['specifier'] : []
|
203
|
+
|
204
|
+
# Deconstruct specifier
|
205
|
+
specifier.split(';').each do |k|
|
206
|
+
j = k.split('=')
|
207
|
+
|
208
|
+
# D=Day of the week, M=Day of the month, O=Month of the year, S=Nth
|
209
|
+
case j[0]
|
210
|
+
when 'D' then dow = j[1].split(',')
|
211
|
+
when 'M' then dom = j[1].split(',')
|
212
|
+
when 'O' then moy = j[1].split(',')
|
213
|
+
when 'S' then nth = j[1].to_i
|
214
|
+
else $log.warn("Unknown specifier: #{k}")
|
200
215
|
end
|
216
|
+
end
|
201
217
|
|
202
|
-
|
203
|
-
|
204
|
-
|
218
|
+
# Build array of DOWs
|
219
|
+
dows = [ nil ]
|
220
|
+
dow.each { |d| dows.push(DOW[d[-2..-1].to_sym]) }
|
205
221
|
|
206
|
-
|
207
|
-
|
208
|
-
|
222
|
+
# Months of the year (O)
|
223
|
+
moy.each do |m|
|
224
|
+
next unless m
|
209
225
|
|
210
|
-
|
211
|
-
|
212
|
-
dow = DOW[n[-2..-1].to_sym]
|
213
|
-
ndate += 1 until ndate.wday == dow
|
214
|
-
ndate = ICalPal.nth(Integer(n[0..1]), n[-2..-1], ndate) unless (n[0] == '0')
|
226
|
+
nsdate = RDT.new(self['sdate'].year, m.to_i, 1)
|
227
|
+
nedate = RDT.new(self['edate'].year, m.to_i, 1)
|
215
228
|
|
216
|
-
#
|
217
|
-
|
218
|
-
|
219
|
-
self['sdate'] = RDT.new(*ndate.to_a[0..2], *self['sdate'].to_a[3..])
|
220
|
-
self['edate'] = RDT.new(*ndate.to_a[0..2], *self['edate'].to_a[3..])
|
221
|
-
retval.push(clone)
|
222
|
-
}) { |i| @self['sday'] == i['sday'] }
|
223
|
-
end
|
229
|
+
# Days of the month (M)
|
230
|
+
dom.each do |x|
|
231
|
+
next unless x
|
224
232
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
233
|
+
self['sdate'] = RDT.new(nsdate.year, nsdate.month, x.to_i)
|
234
|
+
self['edate'] = RDT.new(nedate.year, nedate.month, x.to_i)
|
235
|
+
occurrences.push(clone)
|
236
|
+
end
|
237
|
+
|
238
|
+
# Days of the week (D)
|
239
|
+
if nth
|
240
|
+
self['sdate'] = ICalPal.nth(nth, dows, nsdate)
|
241
|
+
self['edate'] = ICalPal.nth(nth, dows, nedate)
|
242
|
+
occurrences.push(clone)
|
243
|
+
else
|
244
|
+
if dows[0]
|
245
|
+
self['sdate'] = RDT.new(nsdate.year, m.to_i, nsdate.wday)
|
246
|
+
self['edate'] = RDT.new(nedate.year, m.to_i, nedate.wday)
|
247
|
+
occurrences.push(clone)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
230
251
|
|
231
|
-
|
252
|
+
return(occurrences)
|
232
253
|
end
|
233
254
|
|
234
255
|
# Apply frequency and interval
|
@@ -243,6 +264,7 @@ module ICalPal
|
|
243
264
|
when 'weekly' then self[d] += self['interval'] * 7
|
244
265
|
when 'monthly' then self[d] >>= self['interval']
|
245
266
|
when 'yearly' then self[d] >>= self['interval'] * 12
|
267
|
+
else $log.error("Unknown frequency: #{self['frequency']}")
|
246
268
|
end
|
247
269
|
end if self['frequency'] && self['interval']
|
248
270
|
end
|
data/lib/icalPal.rb
CHANGED
@@ -141,7 +141,7 @@ module ICalPal
|
|
141
141
|
# Get the +n+'th +dow+ in month +m+
|
142
142
|
#
|
143
143
|
# @param n [Integer] Integer between -4 and +4
|
144
|
-
# @param dow [
|
144
|
+
# @param dow [Array] Days of the week
|
145
145
|
# @param m [RDT] The RDT with the year and month we're searching
|
146
146
|
# @return [RDT] The resulting day
|
147
147
|
def self.nth(n, dow, m)
|
@@ -155,7 +155,7 @@ module ICalPal
|
|
155
155
|
|
156
156
|
j = 0
|
157
157
|
a[0].step(a[1], step) do |i|
|
158
|
-
j += step if i.wday
|
158
|
+
j += step if dow.any?(i.wday)
|
159
159
|
return i if j == n
|
160
160
|
end
|
161
161
|
end
|
data/lib/options.rb
CHANGED
@@ -55,7 +55,7 @@ module ICalPal
|
|
55
55
|
"Print as FORMAT (default: #{$defaults[:common][:output]})", "[#{OUTFORMATS.join(', ')}]")
|
56
56
|
|
57
57
|
# include/exclude
|
58
|
-
@op.separator("\nIncluding/excluding calendars:\n\n")
|
58
|
+
@op.separator("\nIncluding/excluding accounts, calendars, items:\n\n")
|
59
59
|
|
60
60
|
@op.on('--is=ACCOUNTS', Array, 'List of accounts to include')
|
61
61
|
@op.on('--es=ACCOUNTS', Array, 'List of accounts to exclude')
|
@@ -73,6 +73,9 @@ module ICalPal
|
|
73
73
|
@op.on('--il=LISTS', Array, 'List of reminder lists to include')
|
74
74
|
@op.on('--el=LISTS', Array, 'List of reminder lists to exclude')
|
75
75
|
|
76
|
+
@op.separator('')
|
77
|
+
@op.on('--match=FIELD=REGEXP', String, 'Include only items whose FIELD matches REGEXP (ignoring case)')
|
78
|
+
|
76
79
|
# dates
|
77
80
|
@op.separator("\nChoosing dates:\n\n")
|
78
81
|
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icalPal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Rosen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqlite3
|