todo-jsonl 0.1.5 → 0.1.10

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 +54 -31
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 751d24c27a1e18c59b1a0cd828a8ab8c6dd9f60b15956731101cd2518db9fd1c
4
- data.tar.gz: 8d5968af9ac740a09b39fb8962861caa1150ba047435d4992441c750857c508c
3
+ metadata.gz: 26e087f32b9e0ddb96664aaffcb83aab17a4cf31c75eb651bb1797fa6d7fba09
4
+ data.tar.gz: c298e6c64c3bd28f0d0806c6b12204e74bc7c89e6d32939a2763368cae11e17e
5
5
  SHA512:
6
- metadata.gz: 745240133b49e0d37ccecb25813088e5f75f024151e9e01c3d1993ce8f852cb3d70ee83b79140c2e2dcdae6251246f4eb5d73ad55cd8e439f4e01113e0c99914
7
- data.tar.gz: a9a94cb1f444ca22e69f3c6c3f9a78f42a57f1f61e83e43e6f12655fe854b00d5cf5d2ff95acd0b367c6c2ec87c02724196e305392a2793f9a1ec235ec97ed1c
6
+ metadata.gz: 6221aaca3f2637bd59c35720f2383e9fb6ef1a59faf5604341da0d04148184e504a53bd0d45a18dcd3462141496a5c91bdc0c8bef896c559362ce0670cc1b231
7
+ data.tar.gz: 88c148df544f7bc2fb65a50becac172f9f216cbea27a15666add4eb05ae752834b5f5396d191778be7045f2c856034e11a5e38fb3ef210a570bed92aed75f611
@@ -2,7 +2,7 @@
2
2
 
3
3
  # todo.rb - todo list manager inspired by todo.txt using the jsonl format.
4
4
  #
5
- # Copyright (c) 2020 Gabor Bata
5
+ # Copyright (c) 2020-2021 Gabor Bata
6
6
  #
7
7
  # Permission is hereby granted, free of charge, to any person
8
8
  # obtaining a copy of this software and associated documentation files
@@ -27,8 +27,6 @@
27
27
  require 'json'
28
28
  require 'date'
29
29
 
30
- DATE_FORMAT = '%Y-%m-%d'
31
-
32
30
  COLOR_CODES = {
33
31
  black: 30,
34
32
  red: 31,
@@ -64,21 +62,24 @@ COLORS = {
64
62
  'default' => :magenta
65
63
  }
66
64
 
67
- QUERIES = {
68
- ':active' => 'state=(new|started|blocked)',
69
- ':done' => 'state=done',
70
- ':blocked' => 'state=blocked',
71
- ':started' => 'state=started',
72
- ':new' => 'state=new',
73
- ':all' => 'state=\w+'
74
- }
75
-
76
65
  TODAY = DateTime.now
66
+ NEXT_7_DAYS = (0..6).map do |day| (TODAY.to_date + day) end
67
+ DATE_FORMAT = '%Y-%m-%d'
68
+ DUE_DATE_DAYS = NEXT_7_DAYS.map do |day| day.strftime('%A').downcase end
69
+ DUE_DATES_FOR_QUERIES = NEXT_7_DAYS.map do |day| day.strftime(DATE_FORMAT) end
70
+ DUE_DATE_DAYS_SIMPLE = ['today', 'tomorrow']
77
71
 
78
- DUE_DATE_DAYS = ['today', 'tomorrow']
79
- (2..6).each do |day|
80
- DUE_DATE_DAYS.push((TODAY.to_date + day).strftime('%A').downcase)
81
- end
72
+ QUERIES = {
73
+ ':active' => 'state=(new|started|blocked)',
74
+ ':done' => 'state=done',
75
+ ':blocked' => 'state=blocked',
76
+ ':started' => 'state=started',
77
+ ':new' => 'state=new',
78
+ ':all' => 'state=\w+',
79
+ ':today' => "due=#{DUE_DATES_FOR_QUERIES[0]}",
80
+ ':tomorrow' => "due=#{DUE_DATES_FOR_QUERIES[1]}",
81
+ ':next7days' => "due=(#{DUE_DATES_FOR_QUERIES.join('|')})"
82
+ }
82
83
 
83
84
  PRIORITY_FLAG = '*'
84
85
 
@@ -93,8 +94,9 @@ def usage
93
94
  * start <tasknumber> mark task as started
94
95
  * done <tasknumber> mark task as completed
95
96
  * block <tasknumber> mark task as blocked
97
+ * reset <tasknumber> reset task to new state
96
98
  * prio <tasknumber> toggle high priority flag
97
- * due <tasknumber> <date> set due date
99
+ * due <tasknumber> <date> set due date (in YYYY-MM-DD format)
98
100
 
99
101
  * append <tasknumber> <text> append text to task title
100
102
  * rename <tasknumber> <text> rename task
@@ -194,7 +196,12 @@ end
194
196
 
195
197
  def due_date(item, date = '')
196
198
  tasks = load_tasks(item)
197
- tasks[item][:due] = date.nil? || date.empty? ? nil : Date.parse(date).strftime(DATE_FORMAT)
199
+ day_index = DUE_DATE_DAYS.index(date.to_s.downcase) || DUE_DATE_DAYS_SIMPLE.index(date.to_s.downcase)
200
+ if day_index
201
+ tasks[item][:due] = (TODAY.to_date + day_index).strftime(DATE_FORMAT)
202
+ else
203
+ tasks[item][:due] = date.nil? || date.empty? ? nil : Date.parse(date).strftime(DATE_FORMAT)
204
+ end
198
205
  tasks[item][:modified] = Time.now.strftime(DATE_FORMAT)
199
206
  write_tasks(tasks)
200
207
  list(tasks)
@@ -203,9 +210,10 @@ end
203
210
  def list(tasks = nil, patterns = nil)
204
211
  items = {}
205
212
  tasks = tasks || load_tasks
213
+ task_indent = [tasks.keys.max.to_s.size, 4].max
206
214
  patterns = patterns.nil? || patterns.empty? ? [QUERIES[':active']] : patterns
207
215
  tasks.each do |num, task|
208
- normalized_task = "state=#{task[:state]} #{task[:title]}"
216
+ normalized_task = "state=#{task[:state]} due=#{task[:due]} #{task[:title]}"
209
217
  match = true
210
218
  patterns.each do |pattern|
211
219
  match = false unless /#{QUERIES[pattern] || pattern}/ix.match(normalized_task)
@@ -213,7 +221,7 @@ def list(tasks = nil, patterns = nil)
213
221
  items[num] = task if match
214
222
  end
215
223
  items = items.sort_by do |num, task|
216
- [task[:priority] ? 0 : 1, ORDER[task[:state] || 'default'], task[:due] || 'n/a', num]
224
+ [task[:priority] && task[:state] != 'done' ? 0 : 1, ORDER[task[:state] || 'default'], task[:due] || 'n/a', num]
217
225
  end
218
226
  items.each do |num, task|
219
227
  state = task[:state] || 'default'
@@ -227,13 +235,13 @@ def list(tasks = nil, patterns = nil)
227
235
  if date_diff < 0
228
236
  due_date = colorize("(#{date_diff.abs}d overdue)", :red)
229
237
  elsif date_diff == 0 || date_diff == 1
230
- due_date = colorize("(#{DUE_DATE_DAYS[date_diff]})", :yellow)
238
+ due_date = colorize("(#{DUE_DATE_DAYS_SIMPLE[date_diff]})", :yellow)
231
239
  else
232
240
  due_date = colorize("(#{DUE_DATE_DAYS[date_diff] || task[:due]})", :magenta) if date_diff > 1
233
241
  end
234
242
  due_date = ' ' + due_date
235
243
  end
236
- puts "#{num.to_s.rjust(4, ' ')}:#{priority_flag}#{display_state} #{title}#{due_date}"
244
+ puts "#{num.to_s.rjust(task_indent, ' ')}:#{priority_flag}#{display_state} #{title}#{due_date}"
237
245
  end
238
246
  puts 'No todos found' if items.empty?
239
247
  end
@@ -286,31 +294,46 @@ def read(arguments)
286
294
  args = arguments[1..-1] || []
287
295
  case action
288
296
  when 'add'
289
- add(args.join(' ')) unless args.nil? || args.empty?
297
+ raise action + ' command requires at least one parameter' if args.nil? || args.empty?
298
+ add(args.join(' '))
290
299
  when 'start'
300
+ raise action + ' command can receive only one task number' if args.length > 1
291
301
  args.length == 1 ? change_state(args.first.to_i, 'started') : list(nil, [':started'])
292
302
  when 'done'
303
+ raise action + ' command can receive only one task number' if args.length > 1
293
304
  args.length == 1 ? change_state(args.first.to_i, 'done') : list(nil, [':done'])
294
305
  when 'block'
306
+ raise action + ' command can receive only one task number' if args.length > 1
295
307
  args.length == 1 ? change_state(args.first.to_i, 'blocked') : list(nil, [':blocked'])
308
+ when 'reset'
309
+ raise action + ' command can receive only one task number' if args.length > 1
310
+ args.length == 1 ? change_state(args.first.to_i, 'new') : list(nil, [':new'])
296
311
  when 'prio'
297
- set_priority(args.first.to_i) if args.length == 1
312
+ raise action + ' command requires exactly one parameter' if args.length != 1
313
+ set_priority(args.first.to_i)
298
314
  when 'due'
299
- due_date(args.first.to_i, (args[1..-1] || []).join(' ')) unless args.length < 1
315
+ raise action + ' command requires at least one parameter' if args.length < 1
316
+ due_date(args.first.to_i, (args[1..-1] || []).join(' '))
300
317
  when 'append'
301
- append(args.first.to_i, args[1..-1].join(' ')) unless args.length < 2
318
+ raise action + ' command requires at least two parameters' if args.length < 2
319
+ append(args.first.to_i, args[1..-1].join(' '))
302
320
  when 'rename'
303
- rename(args.first.to_i, args[1..-1].join(' ')) unless args.length < 2
321
+ raise action + ' command requires at least two parameters' if args.length < 2
322
+ rename(args.first.to_i, args[1..-1].join(' '))
304
323
  when 'del'
305
- delete(args.first.to_i) if args.length == 1
324
+ raise action + ' command requires exactly one parameter' if args.length != 1
325
+ delete(args.first.to_i)
306
326
  when 'note'
307
- add_note(args.first.to_i, args[1..-1].join(' ')) unless args.length < 2
327
+ raise action + ' command requires at least two parameters' if args.length < 2
328
+ add_note(args.first.to_i, args[1..-1].join(' '))
308
329
  when 'delnote'
309
- delete_note(args.first.to_i) if args.length == 1
330
+ raise action + ' command requires exactly one parameter' if args.length != 1
331
+ delete_note(args.first.to_i)
310
332
  when 'list'
311
333
  list(nil, args)
312
334
  when 'show'
313
- show(args.first.to_i) if args.length == 1
335
+ raise action + ' command requires exactly one parameter' if args.length != 1
336
+ show(args.first.to_i)
314
337
  when 'help'
315
338
  puts usage
316
339
  when 'repl'
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.5
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabor Bata
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-02 00:00:00.000000000 Z
11
+ date: 2021-01-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: