todo-jsonl 0.1.21 → 0.1.29

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/bin/todo.rb +84 -71
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c21f9ba1d360f6a7d30edf43d125eb6e99ff98eb8b71d2d36c9bb0ae14283e6
4
- data.tar.gz: f2e1bea4d40ff4a612f8ec5976f778e4a339fac49c627c9e85996b928838cdda
3
+ metadata.gz: 2af368dfb4ac9e0f8e6448e005bb7242c509d6bf0ce1e97bdc8783629c3dd77f
4
+ data.tar.gz: dc5f0da8574ea5bda98627c122e9a0bdc7c3d661cba879c4ac09bff3cdb075ba
5
5
  SHA512:
6
- metadata.gz: cd44f645cfc6ace0d7b9c6a799cff82c93e95d110c9364c6efb41e5c93f795191808b991c7091847440e9b3a7c00cbc0b301cdc7b21e4b85b51dbac5b3223706
7
- data.tar.gz: ecba51031774954abe6deb57f5971fed0b9b0786066cd14d8a32d29d849da72f43c7ce305aa9c3e4da9d7b24e7e1d17a02fc49195301e66a4d70fd82af248bcb
6
+ metadata.gz: 1d0b4562ca3af2722f5fb2eb594f248ccaf2b69b18eb2a7f2e19f386da1f60352260631a7afd53e5cf375a3f7c37297a85808a701870b0c2eb73efe9797416e8
7
+ data.tar.gz: 030be81b91d66d0d084dff2c805df49cc1f2705aa020d607a06003d542a139e0f6b6708d307a6e448e14c0ca76b135878e643c5ab54132ac457be506cea43b4f
data/bin/todo.rb CHANGED
@@ -120,12 +120,16 @@ class Todo
120
120
  when 'repl'
121
121
  raise action + ' command has no parameters' if args.length > 0
122
122
  start_repl
123
+ when 'cleanup'
124
+ raise action + ' command requires at least one parameter' if args.nil? || args.empty?
125
+ cleanup(args)
123
126
  else
124
127
  list(nil, arguments)
125
128
  end
126
129
  rescue => error
127
130
  puts "#{colorize('ERROR:', :red)} #{error}"
128
131
  end
132
+ self
129
133
  end
130
134
 
131
135
  private
@@ -152,6 +156,7 @@ class Todo
152
156
  * list <regex> [regex...] list tasks (only active tasks by default)
153
157
  * show <tasknumber> show all task details
154
158
  * repl enter read-eval-print loop mode
159
+ * cleanup <regex> [regex...] cleanup completed tasks by regex
155
160
  * help this help screen
156
161
 
157
162
  With list command the following pre-defined regex patterns can be also used:
@@ -173,15 +178,15 @@ class Todo
173
178
  due_dates_for_queries = next_7_days.map do |day| day.strftime(DATE_FORMAT) end
174
179
 
175
180
  @queries = {
176
- ':active' => 'state=(new|started|blocked)',
177
- ':done' => 'state=done',
178
- ':blocked' => 'state=blocked',
179
- ':started' => 'state=started',
180
- ':new' => 'state=new',
181
- ':all' => 'state=\w+',
182
- ':today' => "due=#{due_dates_for_queries[0]}",
183
- ':tomorrow' => "due=#{due_dates_for_queries[1]}",
184
- ':next7days' => "due=(#{due_dates_for_queries.join('|')})"
181
+ ':active' => lambda do |task| /(new|started|blocked)/.match(task[:state]) end,
182
+ ':done' => lambda do |task| 'done' == task[:state] end,
183
+ ':blocked' => lambda do |task| 'blocked' == task[:state] end,
184
+ ':started' => lambda do |task| 'started' == task[:state] end,
185
+ ':new' => lambda do |task| 'new' == task[:state] end,
186
+ ':all' => lambda do |task| /\w+/.match(task[:state]) end,
187
+ ':today' => lambda do |task| due_dates_for_queries[0] == task[:due] end,
188
+ ':tomorrow' => lambda do |task| due_dates_for_queries[1] == task[:due] end,
189
+ ':next7days' => lambda do |task| /(#{due_dates_for_queries.join('|')})/.match(task[:due]) end
185
190
  }
186
191
  end
187
192
 
@@ -197,9 +202,7 @@ class Todo
197
202
  end
198
203
  end
199
204
  end
200
- if item_to_check && !tasks.has_key?(item_to_check)
201
- raise "#{item_to_check}: No such todo"
202
- end
205
+ raise "#{item_to_check}: No such todo" if item_to_check && !tasks.has_key?(item_to_check)
203
206
  tasks
204
207
  end
205
208
 
@@ -233,22 +236,29 @@ class Todo
233
236
  list
234
237
  end
235
238
 
236
- def append(item, text = '')
239
+ def update_task(item, post_action, update_function)
237
240
  tasks = load_tasks(item)
238
- tasks[item][:title] = [tasks[item][:title], text].join(' ')
241
+ update_function.call(tasks[item])
239
242
  tasks[item][:modified] = @today.strftime(DATE_FORMAT)
240
- postprocess_tags(tasks[item])
241
243
  write_tasks(tasks)
242
- list(tasks)
244
+ case post_action
245
+ when :show then show(item, tasks)
246
+ when :list then list(tasks)
247
+ end
248
+ end
249
+
250
+ def append(item, text = '')
251
+ update_task(item, :list, lambda do |task|
252
+ task[:title] = [task[:title], text].join(' ')
253
+ postprocess_tags(task)
254
+ end)
243
255
  end
244
256
 
245
257
  def rename(item, text)
246
- tasks = load_tasks(item)
247
- tasks[item][:title] = text
248
- tasks[item][:modified] = @today.strftime(DATE_FORMAT)
249
- postprocess_tags(tasks[item])
250
- write_tasks(tasks)
251
- list(tasks)
258
+ update_task(item, :list, lambda do |task|
259
+ task[:title] = text
260
+ postprocess_tags(task)
261
+ end)
252
262
  end
253
263
 
254
264
  def delete(item)
@@ -259,52 +269,38 @@ class Todo
259
269
  end
260
270
 
261
271
  def change_state(item, state, note = nil)
262
- tasks = load_tasks(item)
263
- tasks[item][:state] = state
264
- tasks[item][:modified] = @today.strftime(DATE_FORMAT)
265
- if !note.nil? && !note.empty?
266
- tasks[item][:note] ||= []
267
- tasks[item][:note].push(note)
268
- end
269
- write_tasks(tasks)
270
- list(tasks)
272
+ update_task(item, :list, lambda do |task|
273
+ task[:state] = state
274
+ if !note.nil? && !note.empty?
275
+ task[:note] ||= []
276
+ task[:note].push(note)
277
+ end
278
+ end)
271
279
  end
272
280
 
273
281
  def set_priority(item, note = nil)
274
- tasks = load_tasks(item)
275
- tasks[item][:priority] = !tasks[item][:priority]
276
- tasks[item].delete(:priority) if !tasks[item][:priority]
277
- tasks[item][:modified] = @today.strftime(DATE_FORMAT)
278
- if !note.nil? && !note.empty?
279
- tasks[item][:note] ||= []
280
- tasks[item][:note].push(note)
281
- end
282
- write_tasks(tasks)
283
- list(tasks)
282
+ update_task(item, :list, lambda do |task|
283
+ task[:priority] = !task[:priority]
284
+ task.delete(:priority) if !task[:priority]
285
+ if !note.nil? && !note.empty?
286
+ task[:note] ||= []
287
+ task[:note].push(note)
288
+ end
289
+ end)
284
290
  end
285
291
 
286
292
  def due_date(item, date = '')
287
- tasks = load_tasks(item)
288
- tasks[item][:due] = convert_due_date(date)
289
- tasks[item].delete(:due) if tasks[item][:due].nil?
290
- tasks[item][:modified] = @today.strftime(DATE_FORMAT)
291
- write_tasks(tasks)
292
- list(tasks)
293
+ update_task(item, :list, lambda do |task|
294
+ task[:due] = convert_due_date(date)
295
+ task.delete(:due) if task[:due].nil?
296
+ end)
293
297
  end
294
298
 
295
299
  def list(tasks = nil, patterns = nil)
296
- items = {}
297
300
  tasks = tasks || load_tasks
298
301
  task_indent = [tasks.keys.max.to_s.size, 4].max
299
- patterns = patterns.nil? || patterns.empty? ? [@queries[':active']] : patterns
300
- tasks.each do |num, task|
301
- normalized_task = "state=#{task[:state]} due=#{task[:due]} #{task[:title]}"
302
- match = true
303
- patterns.each do |pattern|
304
- match = false unless /#{@queries[pattern] || pattern}/ix.match(normalized_task)
305
- end
306
- items[num] = task if match
307
- end
302
+ patterns = patterns.nil? || patterns.empty? ? [':active'] : patterns
303
+ items = filter_tasks(tasks, patterns)
308
304
  items = items.sort_by do |num, task|
309
305
  [task[:priority] && task[:state] != 'done' ? 0 : 1, ORDER[task[:state] || 'default'], task[:due] || 'n/a', num]
310
306
  end
@@ -334,24 +330,20 @@ class Todo
334
330
  end
335
331
 
336
332
  def add_note(item, text)
337
- tasks = load_tasks(item)
338
- tasks[item][:note] ||= []
339
- tasks[item][:note].push(text)
340
- tasks[item][:modified] = @today.strftime(DATE_FORMAT)
341
- write_tasks(tasks)
342
- show(item)
333
+ update_task(item, :show, lambda do |task|
334
+ task[:note] ||= []
335
+ task[:note].push(text)
336
+ end)
343
337
  end
344
338
 
345
339
  def delete_note(item)
346
- tasks = load_tasks(item)
347
- tasks[item].delete(:note)
348
- tasks[item][:modified] = @today.strftime(DATE_FORMAT)
349
- write_tasks(tasks)
350
- show(item)
340
+ update_task(item, :show, lambda do |task|
341
+ task.delete(:note)
342
+ end)
351
343
  end
352
344
 
353
- def show(item)
354
- tasks = load_tasks(item)
345
+ def show(item, tasks = nil)
346
+ tasks = tasks || load_tasks(item)
355
347
  tasks[item].each do |key, value|
356
348
  val = value.kind_of?(Array) ? "\n" + value.join("\n") : value
357
349
  puts "#{colorize(key.to_s.rjust(10, ' ') + ':', :cyan)} #{val}"
@@ -371,11 +363,32 @@ class Todo
371
363
  end
372
364
  end
373
365
 
366
+ def cleanup(patterns)
367
+ tasks = load_tasks
368
+ patterns = [':done'] + patterns.to_a
369
+ items = filter_tasks(tasks, patterns)
370
+ items.keys.each do |num| tasks.delete(num) end
371
+ write_tasks(tasks)
372
+ puts "Deleted #{items.size} todo(s)"
373
+ end
374
+
375
+ def filter_tasks(tasks, patterns)
376
+ items = {}
377
+ tasks.each do |num, task|
378
+ match = true
379
+ patterns.each do |pattern|
380
+ match = false unless @queries[pattern] ? @queries[pattern].call(task) : /#{pattern}/ix.match(task[:title])
381
+ end
382
+ items[num] = task if match
383
+ end
384
+ return items
385
+ end
386
+
374
387
  def colorize(text, color)
375
388
  "\e[#{COLOR_CODES[color]}m#{text}\e[0m"
376
389
  end
377
390
 
378
- def convert_due_date(date = '')
391
+ def convert_due_date(date)
379
392
  due = nil
380
393
  day_index = @due_date_days.index(date.to_s.downcase) ||
381
394
  DUE_DATE_DAYS_SIMPLE.index(date.to_s.downcase) ||
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: todo-jsonl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.21
4
+ version: 0.1.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabor Bata
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-03 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: