reminders_txt 0.6.0 → 0.9.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
- checksums.yaml.gz.sig +0 -0
- data/lib/reminders_txt.rb +150 -92
- data.tar.gz.sig +0 -0
- metadata +38 -58
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c91a43ef370d6bca04d588dfabfeef24535af3e2dc90a6517495cbcc445421ae
|
4
|
+
data.tar.gz: 51b59fc426f175a223868ae1eb63e61361f096051c4051b84899ea66b9ad6c30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 940a77c0025c3ffa8c712d234cd6f3caf834e84f3ff083348ead891a650c057135282675f5fc214450e72d16e4ef028547810ee34be3080fa9ff0bf322be514c
|
7
|
+
data.tar.gz: f9861f8c5ee884d7f7bac5e86393389d1ca1e898847c731443e95e519591607fcfcb92108ba9c4cd6b239ec564d0c8e0fb3667c9543575a71a18e406ff045bb0
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/reminders_txt.rb
CHANGED
@@ -7,149 +7,207 @@ require 'dynarex'
|
|
7
7
|
require 'event_nlp'
|
8
8
|
require 'digest/md5'
|
9
9
|
require 'human_speakable'
|
10
|
+
require 'rxfreadwrite'
|
11
|
+
require 'vpim'
|
10
12
|
|
11
13
|
|
14
|
+
class Fixnum
|
15
|
+
def ordinal
|
16
|
+
self.to_s + ( (10...20).include?(self) ? 'th' : %w{ th st nd rd th th th th th th }[self % 10] )
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
12
20
|
class RemindersTxtException < Exception
|
13
|
-
|
14
21
|
|
15
22
|
end
|
16
23
|
|
17
24
|
|
18
25
|
class RemindersTxt
|
19
26
|
using ColouredText
|
20
|
-
include
|
21
|
-
|
27
|
+
include RXFReadWriteModule
|
28
|
+
|
22
29
|
attr_reader :reminders, :dx
|
23
|
-
|
30
|
+
|
24
31
|
def initialize(raw_s='reminders.txt', now: Time.now, debug: false)
|
25
32
|
|
26
33
|
super()
|
27
34
|
|
28
35
|
@now, @debug = now, debug
|
29
|
-
|
36
|
+
|
30
37
|
puts ('@now: ' + @now.inspect).debug if @debug
|
31
38
|
|
32
|
-
|
39
|
+
|
33
40
|
@filepath = raw_s
|
34
|
-
|
41
|
+
|
35
42
|
if raw_s.lines.length > 1 then
|
36
43
|
|
37
44
|
if raw_s.lstrip[0] == '<' then
|
38
45
|
|
39
46
|
@filepath = 'reminders.xml'
|
40
47
|
@dx = Dynarex.new raw_s
|
41
|
-
|
48
|
+
|
42
49
|
else
|
43
50
|
|
44
|
-
@filepath = File.join(
|
45
|
-
@dxfilepath = @filepath.sub(/.txt$/,'.xml')
|
51
|
+
@filepath = File.join(DirX.pwd, 'reminders.txt')
|
52
|
+
@dxfilepath = @filepath.sub(/.txt$/,'.xml')
|
46
53
|
|
47
54
|
@dx = Dynarex.new
|
48
|
-
import_txt(raw_s)
|
49
|
-
|
55
|
+
import_txt(raw_s)
|
56
|
+
|
50
57
|
end
|
51
|
-
|
58
|
+
|
52
59
|
elsif File.extname(@filepath) == '.txt'
|
53
60
|
|
54
61
|
s = FileX.read @filepath
|
55
62
|
@filename = File.basename(@filepath)
|
56
|
-
@dxfilepath = @filepath.sub(/.txt$/,'.xml')
|
57
|
-
|
63
|
+
@dxfilepath = @filepath.sub(/.txt$/,'.xml')
|
64
|
+
|
58
65
|
import_txt(s)
|
59
|
-
|
66
|
+
|
60
67
|
else
|
61
|
-
|
68
|
+
|
62
69
|
@dx = Dynarex.new @filepath
|
63
|
-
|
70
|
+
|
64
71
|
end
|
65
72
|
end
|
66
|
-
|
67
|
-
def add(s)
|
68
73
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
74
|
+
def add(obj)
|
75
|
+
|
76
|
+
if obj.is_a? String then
|
77
|
+
|
78
|
+
s = obj
|
79
|
+
s.strip!
|
80
|
+
r = EventNlp.new(@now, params: {input: s}).parse(s)
|
81
|
+
return if r.nil?
|
82
|
+
|
83
|
+
elsif obj.is_a? OpenStruct
|
84
|
+
|
85
|
+
r = obj
|
86
|
+
|
87
|
+
end
|
88
|
+
|
73
89
|
@reminders << r
|
74
|
-
refresh()
|
90
|
+
refresh()
|
75
91
|
|
76
92
|
end
|
77
|
-
|
93
|
+
|
78
94
|
def after(d)
|
79
|
-
|
95
|
+
|
80
96
|
date = d.is_a?(String) ? Chronic.parse(d).to_datetime : d
|
81
97
|
@dx.filter {|x| DateTime.parse(x.date) > date}
|
82
|
-
|
83
|
-
end
|
84
|
-
|
98
|
+
|
99
|
+
end
|
100
|
+
|
85
101
|
def before(d)
|
86
|
-
|
102
|
+
|
87
103
|
future_date = d.is_a?(String) ? Chronic.parse(d).to_datetime : d
|
88
104
|
@dx.filter {|x| DateTime.parse(x.date) < future_date}
|
89
|
-
|
105
|
+
|
90
106
|
end
|
91
|
-
|
107
|
+
|
92
108
|
def find(s)
|
93
109
|
@dx.filter {|x| x.title =~ /#{s}/i}
|
94
110
|
end
|
95
111
|
|
112
|
+
def import_vcs(filename)
|
113
|
+
|
114
|
+
puts 'filename: ' + filename.inspect if @debug
|
115
|
+
icsfile = FileX.read filename
|
116
|
+
cal = Vpim::Icalendar.decode(icsfile).first
|
117
|
+
puts '*********************' if @debug
|
118
|
+
r = cal.components[0]
|
119
|
+
datestart = "%s %s" % [r.dtstart.day.ordinal, r.dtstart.strftime("%B %Y at %H:%M%P")]
|
120
|
+
event = "%s: %s at %s %s" % [r.categories.join(', '), r.summary, r.location, datestart]
|
121
|
+
|
122
|
+
if r.dtend then
|
123
|
+
|
124
|
+
if r.dtstart.to_date == r.dtend.to_date then
|
125
|
+
event += '-' + r.dtend.strftime("%H:%M%P")
|
126
|
+
else
|
127
|
+
dateend = "%s %s" % [r.dtend.day.ordinal, r.dtend.strftime("%B %Y at %H:%M%P")]
|
128
|
+
event += ' to ' + dateend
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
h = {
|
134
|
+
input: event,
|
135
|
+
title: "%s: %s" % [r.categories.join(', '), r.summary],
|
136
|
+
date: r.dtstart
|
137
|
+
}
|
138
|
+
|
139
|
+
h[:venue] = r.location if r.location
|
140
|
+
h[:end_date] = r.dtend if r.dtend
|
141
|
+
|
142
|
+
add OpenStruct.new(h)
|
143
|
+
|
144
|
+
end
|
145
|
+
|
96
146
|
def upcoming(ndays=5, days: ndays, months: nil)
|
97
|
-
|
147
|
+
|
98
148
|
next_date = if months then
|
99
149
|
@now.to_datetime >> months.to_i
|
100
150
|
else
|
101
151
|
((@now.to_date + days.to_i + 1).to_time - 1).to_datetime
|
102
152
|
end
|
103
|
-
|
153
|
+
|
104
154
|
@dx.filter {|x| DateTime.parse(x.date) <= next_date}
|
105
155
|
end
|
106
|
-
|
156
|
+
|
107
157
|
def updated?()
|
108
158
|
@updated
|
109
|
-
end
|
110
|
-
|
159
|
+
end
|
160
|
+
|
111
161
|
def today()
|
112
162
|
upcoming 0
|
113
163
|
end
|
114
|
-
|
164
|
+
|
115
165
|
def tomorrow()
|
116
166
|
upcoming days: 1
|
117
167
|
end
|
118
|
-
|
168
|
+
|
119
169
|
def this_week()
|
120
170
|
upcoming days: 6
|
121
171
|
end
|
122
|
-
|
172
|
+
|
123
173
|
alias weekahead this_week
|
124
|
-
|
174
|
+
|
175
|
+
def this_month()
|
176
|
+
upcoming months: 1
|
177
|
+
end
|
178
|
+
|
125
179
|
def this_year()
|
126
180
|
upcoming months: 12
|
127
181
|
end
|
128
|
-
|
182
|
+
|
129
183
|
def to_s()
|
130
184
|
|
131
185
|
filename = File.basename(@filepath).sub(/\.xml$/, '.txt')
|
132
186
|
[filename, '=' * filename.length, '', *@dx.all.map(&:input)].join("\n")
|
133
187
|
|
134
188
|
end
|
135
|
-
|
189
|
+
|
136
190
|
def to_xml()
|
137
191
|
@dx.to_xml pretty: true
|
138
|
-
end
|
139
|
-
|
192
|
+
end
|
193
|
+
|
140
194
|
private
|
141
|
-
|
195
|
+
|
142
196
|
def import_txt(s)
|
143
197
|
|
198
|
+
puts 'inside import_txt' if @debug
|
144
199
|
@file_contents = s
|
145
200
|
buffer = s.lines[2..-1]
|
146
201
|
|
147
202
|
@reminders = buffer.inject([]) do |r, x|
|
148
|
-
|
203
|
+
|
204
|
+
puts 'x: ' + x.inspect if @debug
|
149
205
|
x.strip!
|
150
206
|
|
151
207
|
if (x.length > 1) then
|
152
208
|
|
209
|
+
puts '@now:' + @now.inspect if @debug
|
210
|
+
|
153
211
|
rx = EventNlp.new(@now, params: {input: x}, debug: @debug).parse(x)
|
154
212
|
puts ('rx: ' + rx.inspect).debug if @debug
|
155
213
|
r << rx if rx
|
@@ -161,15 +219,15 @@ class RemindersTxt
|
|
161
219
|
@updated = false
|
162
220
|
|
163
221
|
refresh()
|
164
|
-
|
222
|
+
|
165
223
|
end
|
166
|
-
|
224
|
+
|
167
225
|
# synchronise with the XML file and remove any expired dates
|
168
226
|
#
|
169
227
|
def refresh()
|
170
228
|
|
171
229
|
puts 'inside refresh()' if @debug
|
172
|
-
|
230
|
+
|
173
231
|
reminders = @reminders.clone
|
174
232
|
# if XML file doesn't exist, create it
|
175
233
|
|
@@ -178,18 +236,18 @@ class RemindersTxt
|
|
178
236
|
@dx = Dynarex.new @dxfilepath
|
179
237
|
|
180
238
|
@reminders.each do |reminder|
|
181
|
-
|
239
|
+
|
182
240
|
s = reminder.input
|
183
241
|
puts ('refresh() checking s: ' + s).debug if @debug
|
184
242
|
r = @dx.find_by_input s
|
185
|
-
|
243
|
+
|
186
244
|
# it is on file and it's not a recurring or annual event?
|
187
245
|
# use the date from file if the record exists
|
188
246
|
|
189
247
|
if (r and r.recurring.empty? and not s[/\*$/]) then
|
190
248
|
DateTime.parse(r.date)
|
191
|
-
else
|
192
|
-
|
249
|
+
else
|
250
|
+
|
193
251
|
if reminder.date then
|
194
252
|
reminder.date.to_datetime
|
195
253
|
else
|
@@ -197,74 +255,74 @@ class RemindersTxt
|
|
197
255
|
+ reminder.inspect
|
198
256
|
end
|
199
257
|
end
|
200
|
-
|
258
|
+
|
201
259
|
end
|
202
|
-
|
260
|
+
|
203
261
|
else
|
204
262
|
|
205
263
|
save_dx()
|
206
|
-
|
264
|
+
|
207
265
|
end
|
208
266
|
|
209
267
|
# delete expired non-recurring reminders
|
210
268
|
@reminders.reject! do |x|
|
211
|
-
|
269
|
+
|
212
270
|
if @debug then
|
213
271
|
puts 'rejects filter: '
|
214
272
|
puts ' x.input: ' + x.input.inspect
|
215
|
-
puts ' x.date.to_time: ' + x.date.to_time.inspect
|
273
|
+
puts ' x.date.to_time: ' + x.date.to_time.inspect
|
216
274
|
end
|
217
|
-
|
275
|
+
|
218
276
|
x.date.to_time < @now if not x.recurring
|
219
|
-
|
277
|
+
|
220
278
|
end
|
221
|
-
|
279
|
+
|
222
280
|
@reminders.sort_by!(&:date)
|
223
281
|
|
224
282
|
# did the reminders change?
|
225
283
|
puts 'self.to_s: ' + self.to_s if @debug
|
226
|
-
|
284
|
+
|
227
285
|
h1 = (Digest::MD5.new << self.to_s).to_s
|
228
286
|
h2 = (Digest::MD5.new << @file_contents).to_s
|
229
287
|
|
230
288
|
b = h1 != h2
|
231
|
-
|
289
|
+
|
232
290
|
if @debug then
|
233
291
|
puts 'reminders: ' + reminders.inspect
|
234
292
|
puts '@reminders: ' + @reminders.inspect
|
235
293
|
end
|
236
|
-
|
294
|
+
|
237
295
|
if b or @reminders != reminders then
|
238
296
|
|
239
|
-
save_dx()
|
240
|
-
FileX.write File.join(File.dirname(@filepath), 'reminders.txt'), self.to_s
|
297
|
+
save_dx()
|
298
|
+
FileX.write File.join(File.dirname(@filepath), 'reminders.txt'), self.to_s
|
241
299
|
@updated = true
|
242
300
|
else
|
243
301
|
puts 'no update'
|
244
302
|
end
|
245
|
-
|
303
|
+
|
246
304
|
[:refresh, b]
|
247
|
-
|
305
|
+
|
248
306
|
end
|
249
307
|
|
250
308
|
def save_detail()
|
251
|
-
|
309
|
+
|
252
310
|
# fetch the notes file if it exists
|
253
311
|
filepath = File.dirname @dxfilepath
|
254
|
-
|
312
|
+
|
255
313
|
notesfile = File.join(filepath, 'reminder_notes.xml')
|
256
|
-
return unless
|
257
|
-
|
258
|
-
dx = Dynarex.new notesfile
|
314
|
+
return unless FileX.exists? notesfile
|
259
315
|
|
260
|
-
|
316
|
+
dx = Dynarex.new notesfile
|
317
|
+
|
318
|
+
h = dx.all.inject({}) do |r,x|
|
261
319
|
|
262
320
|
a = x.info.lines
|
263
321
|
tag = a.shift[/\w+/]
|
264
322
|
body = a.join.strip
|
265
|
-
|
323
|
+
|
266
324
|
r.merge(tag.to_sym => body)
|
267
|
-
|
325
|
+
|
268
326
|
end
|
269
327
|
|
270
328
|
rows = @dx.all.map do |x|
|
@@ -272,46 +330,46 @@ class RemindersTxt
|
|
272
330
|
hashtag ? x.to_h.merge(info: h[hashtag.to_sym]) : x.to_h
|
273
331
|
end
|
274
332
|
|
275
|
-
dx2 = Dynarex.new 'reminders/reminder(input, title, recurring, ' +
|
333
|
+
dx2 = Dynarex.new 'reminders/reminder(input, title, recurring, ' +
|
276
334
|
'date, end_date, venue, info)'
|
277
335
|
dx2.import rows
|
278
336
|
dx2.save File.join(filepath, 'reminder_details.xml')
|
279
337
|
|
280
338
|
end
|
281
|
-
|
339
|
+
|
282
340
|
def save_dx()
|
283
|
-
|
341
|
+
|
284
342
|
@dx = Dynarex.new(
|
285
343
|
'reminders/reminder(input, title, recurring, date, end_date, venue)')
|
286
344
|
@reminders.each {|x| @dx.create x.to_h}
|
287
345
|
@dx.save @dxfilepath
|
288
|
-
|
346
|
+
|
289
347
|
save_detail()
|
290
|
-
|
348
|
+
|
291
349
|
end
|
292
|
-
|
293
|
-
|
350
|
+
|
351
|
+
|
294
352
|
end
|
295
353
|
|
296
354
|
class RemindersTxtVoice < RemindersTxt
|
297
355
|
using HumanSpeakable
|
298
|
-
|
356
|
+
|
299
357
|
def weekahead() plain_talk(super) end
|
300
358
|
def today() plain_talk(super) end
|
301
359
|
def tomorrow() plain_talk(super) end
|
302
|
-
|
360
|
+
|
303
361
|
private
|
304
|
-
|
362
|
+
|
305
363
|
def plain_talk(entries)
|
306
|
-
|
364
|
+
|
307
365
|
s = entries.all.map do |x|
|
308
366
|
date = DateTime.parse(x.date)
|
309
367
|
"you are at %s, %s at %s." % [(x.venue.empty? ? x.title : x.venue), \
|
310
368
|
date.humanize, date.to_time.humanize]
|
311
369
|
end.join(" Then ")
|
312
370
|
|
313
|
-
s.sub!(/^./){|x| x.upcase}
|
314
|
-
|
371
|
+
s.sub!(/^./){|x| x.upcase}
|
372
|
+
|
315
373
|
end
|
316
|
-
|
374
|
+
|
317
375
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reminders_txt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -11,31 +11,31 @@ cert_chain:
|
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIEXjCCAsagAwIBAgIBATANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFnZW1t
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
+
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMjIwMjAyMTQzOTIyWhcN
|
15
|
+
MjMwMjAyMTQzOTIyWjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
|
16
|
+
cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDyuWp6
|
17
|
+
R95hbPIOVhI9BxGT17x1oAVsTc/BP9VeNAk4MKejK3S+YFv+6M7vXJY5rfW1uNVi
|
18
|
+
NzbEt3akUkYVqUZ8XfNxG2CcUEeMmkk/YiJA9zyXW6hb4txcc1b0ekmRvFCwVqpB
|
19
|
+
ofbQd3JpYZJ7CsH5NkvkZdwUm5KnxqoxxFD9w2u63z3/JAAaJBGOwrYryH0XrX+O
|
20
|
+
2jfw5nxJX8JAPdzR7VfOQV+2i7+0SUSOECtHE4/k+WTu/WnFAzAtqRNE93QB3YF3
|
21
|
+
TA6ospSIyVDQPYqq0tpeUxbYmJQ7kmFF0Kc6ZEXN54tsDhg8aOtsvRtzwcVfZuhc
|
22
|
+
RJQdEbsN195Q4hDFMAIqxBueSuSEujlnVVkXkmvT7ZA6imbb5MPSORKJCAh6uB4c
|
23
|
+
II16+wzXfWikj2OPCdegZKr00kG9LuC0qPfRKJWSVVIlhPsswamiKGj4vMYSPnc/
|
24
|
+
juKrlC7/kmovp6ySjXRA6t03uJjUeMeuvj6eihuxiZdT8r0HeqrMAXltD+ECAwEA
|
25
|
+
AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUX8XM4mRu
|
26
|
+
OpjWNvRPYrT2LntRDG4wJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
|
27
27
|
c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1hc3RlckBqYW1lc3JvYmVydHNvbi5ldTAN
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
BgkqhkiG9w0BAQsFAAOCAYEAfEfGdQvb787MqUj3pRstbdt9ycVqXr7Ctqz1xv72
|
29
|
+
G2lvakKPZOhPuk3HEVcWT3qAxz0m0CqTrP5SBls6Daq0FvOX3CRWsLvlYcenHuqB
|
30
|
+
4tmdC9YPz5Ddqrsc3UHITZQWtBHrhMgO6bU5sUweY3QdinRUVAz+JkS1HnvGdks7
|
31
|
+
noiqQ2iIy8lEiCi2LL5Ov8G0OmOpomOU7jIK6iQIdZB4g6d25iv3um0OzwX8EXDo
|
32
|
+
OaR5OH2c7TKOf9p3FfNmJ7zp0WJDchjqa7MIaJNkMCc3RKrB2ixO5AptuTT2XQ70
|
33
|
+
eSaeDAWlb4pmbBQbCRejl71KOFz3pldcGoVuANq33c3cfTu4C6tbXxRbs2fiNjrn
|
34
|
+
eYgIEbYn1n+EJ9AqQ9jau+5jkpip5X+ix/vHl3oLWLB0rQ20HP/Ftq8zkjMZLuDD
|
35
|
+
tYyvieamfpSjWJEZi7K760qv2dWJ9kwfaJ7Q3TVP4Jjt0Iwep7Gutk7GV3uY35DA
|
36
|
+
iHcajrfKduh5CsLsvkXRjR4E
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date:
|
38
|
+
date: 2022-08-10 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: dynarex
|
@@ -43,82 +43,62 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '1.
|
46
|
+
version: '1.9'
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 1.
|
49
|
+
version: 1.9.11
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '1.
|
56
|
+
version: '1.9'
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 1.
|
59
|
+
version: 1.9.11
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: event_nlp
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '0.
|
66
|
+
version: '0.7'
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
69
|
+
version: 0.7.0
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
74
|
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: '0.
|
76
|
+
version: '0.7'
|
77
77
|
- - ">="
|
78
78
|
- !ruby/object:Gem::Version
|
79
|
-
version: 0.
|
80
|
-
- !ruby/object:Gem::Dependency
|
81
|
-
name: chronic_cron
|
82
|
-
requirement: !ruby/object:Gem::Requirement
|
83
|
-
requirements:
|
84
|
-
- - ">="
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
version: 0.6.0
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0.6'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 0.6.0
|
97
|
-
- - "~>"
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
version: '0.6'
|
79
|
+
version: 0.7.0
|
100
80
|
- !ruby/object:Gem::Dependency
|
101
81
|
name: human_speakable
|
102
82
|
requirement: !ruby/object:Gem::Requirement
|
103
83
|
requirements:
|
104
84
|
- - "~>"
|
105
85
|
- !ruby/object:Gem::Version
|
106
|
-
version: '0.
|
86
|
+
version: '0.2'
|
107
87
|
- - ">="
|
108
88
|
- !ruby/object:Gem::Version
|
109
|
-
version: 0.
|
89
|
+
version: 0.2.0
|
110
90
|
type: :runtime
|
111
91
|
prerelease: false
|
112
92
|
version_requirements: !ruby/object:Gem::Requirement
|
113
93
|
requirements:
|
114
94
|
- - "~>"
|
115
95
|
- !ruby/object:Gem::Version
|
116
|
-
version: '0.
|
96
|
+
version: '0.2'
|
117
97
|
- - ">="
|
118
98
|
- !ruby/object:Gem::Version
|
119
|
-
version: 0.
|
99
|
+
version: 0.2.0
|
120
100
|
description:
|
121
|
-
email:
|
101
|
+
email: digital.robertson@gmail.com
|
122
102
|
executables: []
|
123
103
|
extensions: []
|
124
104
|
extra_rdoc_files: []
|
@@ -143,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
123
|
- !ruby/object:Gem::Version
|
144
124
|
version: '0'
|
145
125
|
requirements: []
|
146
|
-
rubygems_version: 3.
|
126
|
+
rubygems_version: 3.3.7
|
147
127
|
signing_key:
|
148
128
|
specification_version: 4
|
149
129
|
summary: Reads and updates diary reminders from a plain text file
|
metadata.gz.sig
CHANGED
Binary file
|