todo-jsonl 0.1.6 → 0.1.11

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 +52 -30
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bfdc7f1aa08b2e153cb2db14f20487511c3dd4064b5f11164d5f6f503b65ba2
4
- data.tar.gz: 6cc8401c245972537c76589ed4cab56b712006216bf1a442269ccb5aa2961cf0
3
+ metadata.gz: 8e4b32533e988a9c46ea11df68063b0ce2eefcc1941ea9871471264aa45a3eb7
4
+ data.tar.gz: 96c5880a633cb3e9aaea2e9b39b6e74e542e594d6f4fac98b7018161330bbe9a
5
5
  SHA512:
6
- metadata.gz: 434b78f9f7f72bfbf127d57e24ab1a48558495e2f79a807554ddfe49197ea20174c68e09ea705215a222ac1acfbcc5114a719dfc301aa96f4f6a5969848c88f4
7
- data.tar.gz: 99a3bf80d303e66da13b92a6fa95ec5a31db4623f2fbe9a28f8a7b2b623e858312b397777cb6d297fe2b8e7f96e9f218a961bf6c5606194240c1aa26ec568c08
6
+ metadata.gz: d246676dd37231499da9d52eee2f5abdaf9d85790c63afc3a4814b6b91cbfb5efda9cb595c365fdb0cf96bdcbbe5751cb05f433c9e6e9d6ce36b120773b88a19
7
+ data.tar.gz: 114c0e82ad9929615de9405531176f2bfe0969e05b7f4deb27a4002406d37abe253d7824519cc5955f98a75b986f7cccbb16841fc90bad043b3e59c1afd709f7
data/bin/todo.rb CHANGED
@@ -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
 
@@ -95,7 +96,7 @@ def usage
95
96
  * block <tasknumber> mark task as blocked
96
97
  * reset <tasknumber> reset task to new state
97
98
  * prio <tasknumber> toggle high priority flag
98
- * due <tasknumber> <date> set due date
99
+ * due <tasknumber> <date> set due date (in YYYY-MM-DD format)
99
100
 
100
101
  * append <tasknumber> <text> append text to task title
101
102
  * rename <tasknumber> <text> rename task
@@ -113,6 +114,8 @@ def usage
113
114
 
114
115
  Legend:
115
116
  #{STATES.select { |k, v| k != 'default' }.map { |k, v| "#{k} #{v}" }.join(', ') }, priority #{PRIORITY_FLAG}
117
+
118
+ Todo file: #{TODO_FILE}
116
119
  USAGE
117
120
  end
118
121
 
@@ -195,7 +198,12 @@ end
195
198
 
196
199
  def due_date(item, date = '')
197
200
  tasks = load_tasks(item)
198
- tasks[item][:due] = date.nil? || date.empty? ? nil : Date.parse(date).strftime(DATE_FORMAT)
201
+ day_index = DUE_DATE_DAYS.index(date.to_s.downcase) || DUE_DATE_DAYS_SIMPLE.index(date.to_s.downcase)
202
+ if day_index
203
+ tasks[item][:due] = (TODAY.to_date + day_index).strftime(DATE_FORMAT)
204
+ else
205
+ tasks[item][:due] = date.nil? || date.empty? ? nil : Date.parse(date).strftime(DATE_FORMAT)
206
+ end
199
207
  tasks[item][:modified] = Time.now.strftime(DATE_FORMAT)
200
208
  write_tasks(tasks)
201
209
  list(tasks)
@@ -204,9 +212,10 @@ end
204
212
  def list(tasks = nil, patterns = nil)
205
213
  items = {}
206
214
  tasks = tasks || load_tasks
215
+ task_indent = [tasks.keys.max.to_s.size, 4].max
207
216
  patterns = patterns.nil? || patterns.empty? ? [QUERIES[':active']] : patterns
208
217
  tasks.each do |num, task|
209
- normalized_task = "state=#{task[:state]} #{task[:title]}"
218
+ normalized_task = "state=#{task[:state]} due=#{task[:due]} #{task[:title]}"
210
219
  match = true
211
220
  patterns.each do |pattern|
212
221
  match = false unless /#{QUERIES[pattern] || pattern}/ix.match(normalized_task)
@@ -228,13 +237,13 @@ def list(tasks = nil, patterns = nil)
228
237
  if date_diff < 0
229
238
  due_date = colorize("(#{date_diff.abs}d overdue)", :red)
230
239
  elsif date_diff == 0 || date_diff == 1
231
- due_date = colorize("(#{DUE_DATE_DAYS[date_diff]})", :yellow)
240
+ due_date = colorize("(#{DUE_DATE_DAYS_SIMPLE[date_diff]})", :yellow)
232
241
  else
233
242
  due_date = colorize("(#{DUE_DATE_DAYS[date_diff] || task[:due]})", :magenta) if date_diff > 1
234
243
  end
235
244
  due_date = ' ' + due_date
236
245
  end
237
- puts "#{num.to_s.rjust(4, ' ')}:#{priority_flag}#{display_state} #{title}#{due_date}"
246
+ puts "#{num.to_s.rjust(task_indent, ' ')}:#{priority_flag}#{display_state} #{title}#{due_date}"
238
247
  end
239
248
  puts 'No todos found' if items.empty?
240
249
  end
@@ -287,33 +296,46 @@ def read(arguments)
287
296
  args = arguments[1..-1] || []
288
297
  case action
289
298
  when 'add'
290
- add(args.join(' ')) unless args.nil? || args.empty?
299
+ raise action + ' command requires at least one parameter' if args.nil? || args.empty?
300
+ add(args.join(' '))
291
301
  when 'start'
302
+ raise action + ' command can receive only one task number' if args.length > 1
292
303
  args.length == 1 ? change_state(args.first.to_i, 'started') : list(nil, [':started'])
293
304
  when 'done'
305
+ raise action + ' command can receive only one task number' if args.length > 1
294
306
  args.length == 1 ? change_state(args.first.to_i, 'done') : list(nil, [':done'])
295
307
  when 'block'
308
+ raise action + ' command can receive only one task number' if args.length > 1
296
309
  args.length == 1 ? change_state(args.first.to_i, 'blocked') : list(nil, [':blocked'])
297
310
  when 'reset'
311
+ raise action + ' command can receive only one task number' if args.length > 1
298
312
  args.length == 1 ? change_state(args.first.to_i, 'new') : list(nil, [':new'])
299
313
  when 'prio'
300
- set_priority(args.first.to_i) if args.length == 1
314
+ raise action + ' command requires exactly one parameter' if args.length != 1
315
+ set_priority(args.first.to_i)
301
316
  when 'due'
302
- due_date(args.first.to_i, (args[1..-1] || []).join(' ')) unless args.length < 1
317
+ raise action + ' command requires at least one parameter' if args.length < 1
318
+ due_date(args.first.to_i, (args[1..-1] || []).join(' '))
303
319
  when 'append'
304
- append(args.first.to_i, args[1..-1].join(' ')) unless args.length < 2
320
+ raise action + ' command requires at least two parameters' if args.length < 2
321
+ append(args.first.to_i, args[1..-1].join(' '))
305
322
  when 'rename'
306
- rename(args.first.to_i, args[1..-1].join(' ')) unless args.length < 2
323
+ raise action + ' command requires at least two parameters' if args.length < 2
324
+ rename(args.first.to_i, args[1..-1].join(' '))
307
325
  when 'del'
308
- delete(args.first.to_i) if args.length == 1
326
+ raise action + ' command requires exactly one parameter' if args.length != 1
327
+ delete(args.first.to_i)
309
328
  when 'note'
310
- add_note(args.first.to_i, args[1..-1].join(' ')) unless args.length < 2
329
+ raise action + ' command requires at least two parameters' if args.length < 2
330
+ add_note(args.first.to_i, args[1..-1].join(' '))
311
331
  when 'delnote'
312
- delete_note(args.first.to_i) if args.length == 1
332
+ raise action + ' command requires exactly one parameter' if args.length != 1
333
+ delete_note(args.first.to_i)
313
334
  when 'list'
314
335
  list(nil, args)
315
336
  when 'show'
316
- show(args.first.to_i) if args.length == 1
337
+ raise action + ' command requires exactly one parameter' if args.length != 1
338
+ show(args.first.to_i)
317
339
  when 'help'
318
340
  puts usage
319
341
  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.6
4
+ version: 0.1.11
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-04 00:00:00.000000000 Z
11
+ date: 2021-02-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: