todo-jsonl 0.1.30 → 1.0.1

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 +39 -46
  3. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e18e67f8684606fee2693456e247af3edd78926e4d022a12f96c3b255dab3e1c
4
- data.tar.gz: 93c21f98eece4e5fce236c5f485073a3d9b052be489cc30dca25a59bab2413e2
3
+ metadata.gz: 2691d07e42991c659c196150c96364fc4ccf5b0a40d07d4bc932c74cd6b5e5e4
4
+ data.tar.gz: b1c1b92535378ea04dfa9d081aa6843cd54f9bad4980316cf84d6d55a2ae3fdb
5
5
  SHA512:
6
- metadata.gz: 6addcea04123ade9a05649cf9d6b9ac569a23f6210b103fc715076cadd6775c0ca738cb6a3b3733f28270d66cb1e4d7bbe21a92b20c51b4a2e032b40b7942fed
7
- data.tar.gz: 8131e3ccc7e5e28168b16582bb989474b79257284a0effc9d072acfe18844de6684873e295fc99da89535ddefb8a5ab1fcf85ce3e4d968828cff6973224d1151
6
+ metadata.gz: 4ff802f21722a328bc911c475ee58deb6613447fbbdd3213bab6ee6755ca551b07345b252f41b2b005b036986f8361af3b6a2b813b2b28c070a775b3b252372a
7
+ data.tar.gz: 2b1e00730185745a326fb4e33748a1787d34c64e5ea85339dbb5b464d19062963e8df7f6da8ebe61662d6c6e6bcdd047b0b64dda4a2c9e1df8bcfb5dbf1a5795
data/bin/todo.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # todo.rb - todo list manager inspired by todo.txt using the jsonl format.
3
+ # todo.rb - todo list manager on the command-line
4
+ # inspired by todo.txt using the jsonl format.
4
5
  #
5
6
  # Copyright (c) 2020-2021 Gabor Bata
6
7
  #
@@ -28,7 +29,6 @@ require 'json'
28
29
  require 'date'
29
30
 
30
31
  class Todo
31
-
32
32
  COLOR_CODES = {
33
33
  black: 30,
34
34
  red: 31,
@@ -159,8 +159,8 @@ class Todo
159
159
  * cleanup <regex> [regex...] cleanup completed tasks by regex
160
160
  * help this help screen
161
161
 
162
- With list command the following pre-defined regex patterns can be also used:
163
- #{@queries.keys.join(', ')}
162
+ With list command the following pre-defined queries can be also used:
163
+ #{@queries.keys.each_with_index.map { |k, i| (i == 8 ? "\n" : '') + k }.join(', ')}
164
164
 
165
165
  Due dates can be also added via tags in task title: "due:YYYY-MM-DD"
166
166
 
@@ -173,20 +173,23 @@ class Todo
173
173
 
174
174
  def setup
175
175
  @today = Date.today
176
- next_7_days = (0..6).map do |day| @today + day end
177
- @due_date_days = next_7_days.map do |day| day.strftime('%A').downcase end
178
- due_dates_for_queries = next_7_days.map do |day| day.strftime(DATE_FORMAT) end
179
-
176
+ next_7_days = (0..6).map { |day| @today + day }
177
+ @due_date_days = next_7_days.map { |day| day.strftime('%A').downcase }
178
+ due_dates_for_queries = next_7_days.map { |day| day.strftime(DATE_FORMAT) }
180
179
  @queries = {
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
180
+ ':active' => lambda { |task| /(new|started|blocked)/.match(task[:state]) },
181
+ ':done' => lambda { |task| 'done' == task[:state] },
182
+ ':blocked' => lambda { |task| 'blocked' == task[:state] },
183
+ ':started' => lambda { |task| 'started' == task[:state] },
184
+ ':new' => lambda { |task| 'new' == task[:state] },
185
+ ':all' => lambda { |task| /\w+/.match(task[:state]) },
186
+ ':priority' => lambda { |task| task[:priority] },
187
+ ':note' => lambda { |task| task[:note] && !task[:note].empty? },
188
+ ':today' => lambda { |task| due_dates_for_queries[0] == task[:due] },
189
+ ':tomorrow' => lambda { |task| due_dates_for_queries[1] == task[:due] },
190
+ ':next7days' => lambda { |task| /(#{due_dates_for_queries.join('|')})/.match(task[:due]) },
191
+ ':overdue' => lambda { |task| task[:due] && task[:due] < due_dates_for_queries[0] },
192
+ ':due' => lambda { |task| task[:due] }
190
193
  }
191
194
  end
192
195
 
@@ -225,8 +228,8 @@ class Todo
225
228
 
226
229
  def add(text)
227
230
  task = {
228
- state: 'new',
229
- title: text,
231
+ state: 'new',
232
+ title: text,
230
233
  modified: @today.strftime(DATE_FORMAT)
231
234
  }
232
235
  postprocess_tags(task)
@@ -247,7 +250,7 @@ class Todo
247
250
  end
248
251
  end
249
252
 
250
- def append(item, text = '')
253
+ def append(item, text)
251
254
  update_task(item, :list, lambda do |task|
252
255
  task[:title] = [task[:title], text].join(' ')
253
256
  postprocess_tags(task)
@@ -297,21 +300,20 @@ class Todo
297
300
  end
298
301
 
299
302
  def list(tasks = nil, patterns = nil)
300
- tasks = tasks || load_tasks
303
+ tasks ||= load_tasks
301
304
  task_indent = [tasks.keys.max.to_s.size, 4].max
302
- patterns = patterns.nil? || patterns.empty? ? [':active'] : patterns
303
- items = filter_tasks(tasks, patterns)
304
- items = items.sort_by do |num, task|
305
+ patterns ||= []
306
+ patterns += [':active'] if (patterns & [':active', ':done', ':blocked', ':started', ':new', ':all']).empty?
307
+ items = filter_tasks(tasks, patterns).sort_by do |num, task|
305
308
  [task[:priority] && task[:state] != 'done' ? 0 : 1, ORDER[task[:state] || 'default'], task[:due] || 'n/a', num]
306
309
  end
307
310
  items.each do |num, task|
308
311
  state = task[:state] || 'default'
309
- color = COLORS[state]
310
- display_state = colorize(STATES[state], color)
312
+ display_state = colorize(STATES[state], COLORS[state])
311
313
  title = task[:title].gsub(CONTEXT_TAG_PATTERN) do |tag|
312
314
  (tag.start_with?(' ') ? ' ' : '') + colorize(tag.strip, :cyan)
313
315
  end
314
- priority_flag = task[:priority] ? colorize(PRIORITY_FLAG, :red) : ' '
316
+ priority_flag = task[:priority] && state != 'done' ? colorize(PRIORITY_FLAG, :red) : ' '
315
317
  due_date = ''
316
318
  if task[:due] && state != 'done'
317
319
  date_diff = (Date.strptime(task[:due], DATE_FORMAT) - @today).to_i
@@ -343,7 +345,7 @@ class Todo
343
345
  end
344
346
 
345
347
  def show(item, tasks = nil)
346
- tasks = tasks || load_tasks(item)
348
+ tasks ||= load_tasks(item)
347
349
  tasks[item].each do |key, value|
348
350
  val = value.kind_of?(Array) ? "\n" + value.join("\n") : value
349
351
  puts "#{colorize(key.to_s.rjust(10, ' ') + ':', :cyan)} #{val}"
@@ -367,40 +369,31 @@ class Todo
367
369
  tasks = load_tasks
368
370
  patterns = [':done'] + patterns.to_a
369
371
  items = filter_tasks(tasks, patterns)
370
- items.keys.each do |num| tasks.delete(num) end
372
+ items.each_key { |num| tasks.delete(num) }
371
373
  write_tasks(tasks)
372
374
  puts "Deleted #{items.size} todo(s)"
373
375
  end
374
376
 
375
377
  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])
378
+ patterns = patterns.uniq
379
+ tasks.select do |num, task|
380
+ patterns.all? do |pattern|
381
+ @queries[pattern] ? @queries[pattern].call(task) : /#{pattern}/ix.match(task[:title])
381
382
  end
382
- items[num] = task if match
383
383
  end
384
- return items
385
384
  end
386
385
 
387
386
  def colorize(text, color)
388
- "\e[#{COLOR_CODES[color]}m#{text}\e[0m"
387
+ "\e[#{COLOR_CODES[color] || 37}m#{text}\e[0m"
389
388
  end
390
389
 
391
390
  def convert_due_date(date)
392
- due = nil
393
391
  day_index = @due_date_days.index(date.to_s.downcase) ||
394
392
  DUE_DATE_DAYS_SIMPLE.index(date.to_s.downcase) ||
395
- @due_date_days.map do |day| day[0..2] end.index(date.to_s.downcase)
396
- if day_index
397
- due = (@today + day_index).strftime(DATE_FORMAT)
398
- else
399
- due = date.nil? || date.empty? ? nil : Date.strptime(date, DATE_FORMAT).strftime(DATE_FORMAT)
400
- end
401
- return due
393
+ @due_date_days.map { |day| day[0..2] }.index(date.to_s.downcase)
394
+ return (@today + day_index).strftime(DATE_FORMAT) if day_index
395
+ date.nil? || date.empty? ? nil : Date.strptime(date, DATE_FORMAT).strftime(DATE_FORMAT)
402
396
  end
403
-
404
397
  end
405
398
 
406
399
  Todo.new.execute(ARGV)
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.30
4
+ version: 1.0.1
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-11 00:00:00.000000000 Z
11
+ date: 2021-03-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -42,5 +42,6 @@ requirements: []
42
42
  rubygems_version: 3.0.3
43
43
  signing_key:
44
44
  specification_version: 4
45
- summary: todo list manager inspired by todo.txt using the jsonl format
45
+ summary: todo list manager on the command-line inspired by todo.txt using the jsonl
46
+ format
46
47
  test_files: []