reminders_txt 0.6.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97b8979998448a59a4606ca6222c74a8c923be7439f67f3fc39835a6a59752e6
4
- data.tar.gz: 6efdd23bdbe788704510861ee5cba874baa170baa8c8c93397fbde295ff50e82
3
+ metadata.gz: c91a43ef370d6bca04d588dfabfeef24535af3e2dc90a6517495cbcc445421ae
4
+ data.tar.gz: 51b59fc426f175a223868ae1eb63e61361f096051c4051b84899ea66b9ad6c30
5
5
  SHA512:
6
- metadata.gz: 3621d7e5a617a9a8cba619cf87e4a59e6136d04a943448bd6badba010a26b9644194dddf56cf6c6c119584da31f6490c9a330378be775a8b4ddfe6c63317fac3
7
- data.tar.gz: e8575e6dec4d6e75674cd5d404b8e151c1bc0bbe4f531b5ed042644849f779bc77c4ecf687d9e598263f82a1fe9fdf3874fbdcf5ad5cfd82b456c998958aee28
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 RXFHelperModule
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(Dir.pwd, 'reminders.txt')
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
- s.strip!
70
- r = EventNlp.new(@now, params: {input: s}).parse(s)
71
- return if r.nil?
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 File.exists? notesfile
257
-
258
- dx = Dynarex.new notesfile
314
+ return unless FileX.exists? notesfile
259
315
 
260
- h = dx.all.inject({}) do |r,x|
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.6.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
- YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMTkwOTEwMjIxMDAyWhcN
15
- MjAwOTA5MjIxMDAyWjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
16
- cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCpl8al
17
- 48UWqZgRIgs1EURPZMVXv4p1TmdXDvuFCYQjzWBCsPc5qnzCV+AMPbaJw5swxdu5
18
- MDWuSoxTUiMdfL8qNpE8RVB7ldH9FZDXBbTKoJITgvt07i9MEyvKXqpIpQEnn434
19
- yUlWz9F+EriEZ5qJx8WNINX5HCyM64qX9ToQI0jm8SDwhW3YLjSuEJ/rU2iXyE4c
20
- +ff9j5jP9OHMyr2K1H3DDsZmds8MsitRbLBMrOIJh802z434sHh4SzcSQkzr15GP
21
- nzoS8zEnjjWmhO6v09vql6ZX0Y42EuxnY9k7y58VE5fxaRmEHEGC7GjRxU7PR02v
22
- NdWgYUVxGsAF4Wl920DzBjorQ3Qw8iCUpcH8cW/tiZU/5ZIkpg1a2oPesxlh5YSW
23
- ok33GWOabC41EVc20nWLDzJ4kge2RTvHKpz81Cptp3LdsKMYEDpBt3qtEsyyN51e
24
- nXQB7rqS+sLX7EY9QpGD0ojS0bH3Nb1H0bYeiFWHK0T7PySxVe2pqqh+0KkCAwEA
25
- AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUDJ1o5bjL
26
- DZgKwH/ezPMECD9zOwwwJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
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
- BgkqhkiG9w0BAQsFAAOCAYEAO3sBZzLrd1Ak8b2Ckw45Xc+51Nn1Qr6Pdk8erw4T
29
- 46gst7gdgZ5D62Oe05gl6eLW8MK1IOfdMx5YEVsNCpJYpI1tXGO7ZIBVguYLAWom
30
- RPHfFJraSTGwjpU+Zyr6uyfclR1dVaqkapgtikrJ8/cqG/BCYoxAIraiLn1kJ+tF
31
- G1bNlaBEH2kqwAHJyMbMLrNIdp76w2D3IjarX6eOLXoD8W3uR7mI4sGUaCW5UXJz
32
- fZnNj4Xwivo6NlRNi5CHOUrplVAgRGHatMu8MtrZyIr8uj+IvdNB3rkuh4Z3ftE5
33
- ISrHXet/Gt6V9kRKVY8ieUtIeaEjsQS0oaopkHw6CA/3KI1uiVxSLqvmnor8PQwb
34
- qKvKKjYnJWjRMj+Gl5pjhdu47S97fR7BjtXU0LuDf5IH1r2PgXRSMfbM91LSzzge
35
- BTEl/Y9FxPLxYQmps8Ut058T2G3hVHzaOckIxdhCwYyzA4Bcrukfok/+wdYe/NW4
36
- CUFAhVCmmO+WPBpim/B6NBmp
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: 2019-09-10 00:00:00.000000000 Z
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.8'
46
+ version: '1.9'
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 1.8.20
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.8'
56
+ version: '1.9'
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 1.8.20
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.5'
66
+ version: '0.7'
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 0.5.4
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.5'
76
+ version: '0.7'
77
77
  - - ">="
78
78
  - !ruby/object:Gem::Version
79
- version: 0.5.4
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.1'
86
+ version: '0.2'
107
87
  - - ">="
108
88
  - !ruby/object:Gem::Version
109
- version: 0.1.3
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.1'
96
+ version: '0.2'
117
97
  - - ">="
118
98
  - !ruby/object:Gem::Version
119
- version: 0.1.3
99
+ version: 0.2.0
120
100
  description:
121
- email: james@jamesrobertson.eu
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.0.1
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