todo-jsonl 0.1.11 → 0.1.12

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 +47 -22
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e4b32533e988a9c46ea11df68063b0ce2eefcc1941ea9871471264aa45a3eb7
4
- data.tar.gz: 96c5880a633cb3e9aaea2e9b39b6e74e542e594d6f4fac98b7018161330bbe9a
3
+ metadata.gz: bb612ac4efe61a2da25f5438e4e158612ca1d1837484a5338d8768e527fd9e71
4
+ data.tar.gz: '079821ed0936b0a250133b18304a1110d59b3fa5f5e008c228ae4c9d01a98799'
5
5
  SHA512:
6
- metadata.gz: d246676dd37231499da9d52eee2f5abdaf9d85790c63afc3a4814b6b91cbfb5efda9cb595c365fdb0cf96bdcbbe5751cb05f433c9e6e9d6ce36b120773b88a19
7
- data.tar.gz: 114c0e82ad9929615de9405531176f2bfe0969e05b7f4deb27a4002406d37abe253d7824519cc5955f98a75b986f7cccbb16841fc90bad043b3e59c1afd709f7
6
+ metadata.gz: d6a531a29f85db3d3af7baa47f4b26485639db66eebbe028d3327375ff0ebf5d68958a6713a82bb6ae10c3e5beb305d374273ccc82529e4eccc4c0494bfec95f
7
+ data.tar.gz: 250acb20cb6edf8b5cfac5fc3b568f5cfc2f72245e0884618c7d8143c5a63e81bed6dfa699aa833d4fc96bff9ac62475e2f65647c3e3f9f342725b623d0101b5
data/bin/todo.rb CHANGED
@@ -69,6 +69,9 @@ DUE_DATE_DAYS = NEXT_7_DAYS.map do |day| day.strftime('%A').downcase end
69
69
  DUE_DATES_FOR_QUERIES = NEXT_7_DAYS.map do |day| day.strftime(DATE_FORMAT) end
70
70
  DUE_DATE_DAYS_SIMPLE = ['today', 'tomorrow']
71
71
 
72
+ DUE_DATE_TAG_PATTERN = /(^| )due:([a-zA-Z0-9-]+)/
73
+ CONTEXT_TAG_PATTERN = /(^| )[@+][\w-]+/
74
+
72
75
  QUERIES = {
73
76
  ':active' => 'state=(new|started|blocked)',
74
77
  ':done' => 'state=done',
@@ -91,12 +94,12 @@ def usage
91
94
 
92
95
  Commands:
93
96
  * add <text> add new task
94
- * start <tasknumber> mark task as started
95
- * done <tasknumber> mark task as completed
96
- * block <tasknumber> mark task as blocked
97
- * reset <tasknumber> reset task to new state
97
+ * start <tasknumber> [text] mark task as started, with optional note
98
+ * done <tasknumber> [text] mark task as completed, with optional note
99
+ * block <tasknumber> [text] mark task as blocked, with optional note
100
+ * reset <tasknumber> [text] reset task to new state, with optional note
98
101
  * prio <tasknumber> toggle high priority flag
99
- * due <tasknumber> <date> set due date (in YYYY-MM-DD format)
102
+ * due <tasknumber> [date] set/unset due date (in YYYY-MM-DD format)
100
103
 
101
104
  * append <tasknumber> <text> append text to task title
102
105
  * rename <tasknumber> <text> rename task
@@ -112,6 +115,8 @@ def usage
112
115
  With list command the following pre-defined regex patterns can be also used:
113
116
  #{QUERIES.keys.join(', ')}
114
117
 
118
+ Due dates can be also added via tags in task title: "due:YYYY-MM-DD"
119
+
115
120
  Legend:
116
121
  #{STATES.select { |k, v| k != 'default' }.map { |k, v| "#{k} #{v}" }.join(', ') }, priority #{PRIORITY_FLAG}
117
122
 
@@ -145,12 +150,22 @@ def write_tasks(tasks)
145
150
  end
146
151
  end
147
152
 
153
+ def postprocess_tags(task)
154
+ title = task[:title]
155
+ match_data = title.match(DUE_DATE_TAG_PATTERN)
156
+ if match_data
157
+ task[:title] = title.gsub(DUE_DATE_TAG_PATTERN, '')
158
+ task[:due] = convert_due_date(match_data[2])
159
+ end
160
+ end
161
+
148
162
  def add(text)
149
163
  task = {
150
164
  state: 'new',
151
165
  title: text,
152
166
  modified: Time.now.strftime(DATE_FORMAT)
153
167
  }
168
+ postprocess_tags(task)
154
169
  File.open(TODO_FILE, 'a:UTF-8') do |file|
155
170
  file.write(JSON.generate(task) + "\n")
156
171
  end
@@ -161,6 +176,7 @@ def append(item, text = '')
161
176
  tasks = load_tasks(item)
162
177
  tasks[item][:title] = [tasks[item][:title], text].join(' ')
163
178
  tasks[item][:modified] = Time.now.strftime(DATE_FORMAT)
179
+ postprocess_tags(tasks[item])
164
180
  write_tasks(tasks)
165
181
  list(tasks)
166
182
  end
@@ -169,6 +185,7 @@ def rename(item, text)
169
185
  tasks = load_tasks(item)
170
186
  tasks[item][:title] = text
171
187
  tasks[item][:modified] = Time.now.strftime(DATE_FORMAT)
188
+ postprocess_tags(tasks[item])
172
189
  write_tasks(tasks)
173
190
  list(tasks)
174
191
  end
@@ -180,10 +197,14 @@ def delete(item)
180
197
  list
181
198
  end
182
199
 
183
- def change_state(item, state)
200
+ def change_state(item, state, note = nil)
184
201
  tasks = load_tasks(item)
185
202
  tasks[item][:state] = state
186
203
  tasks[item][:modified] = Time.now.strftime(DATE_FORMAT)
204
+ if !note.nil? && !note.empty?
205
+ tasks[item][:note] ||= []
206
+ tasks[item][:note].push(note)
207
+ end
187
208
  write_tasks(tasks)
188
209
  list(tasks)
189
210
  end
@@ -196,14 +217,9 @@ def set_priority(item)
196
217
  list(tasks)
197
218
  end
198
219
 
199
- def due_date(item, date = '')
220
+ def due_date(item, date = '', task = nil)
200
221
  tasks = load_tasks(item)
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
222
+ tasks[item][:due] = convert_due_date(date)
207
223
  tasks[item][:modified] = Time.now.strftime(DATE_FORMAT)
208
224
  write_tasks(tasks)
209
225
  list(tasks)
@@ -229,7 +245,9 @@ def list(tasks = nil, patterns = nil)
229
245
  state = task[:state] || 'default'
230
246
  color = COLORS[state]
231
247
  display_state = colorize(STATES[state], color)
232
- title = task[:title].gsub(/@\w+/) { |tag| colorize(tag, :cyan) }
248
+ title = task[:title].gsub(CONTEXT_TAG_PATTERN) do |tag|
249
+ (tag.start_with?(' ') ? ' ' : '') + colorize(tag.strip, :cyan)
250
+ end
233
251
  priority_flag = task[:priority] ? colorize(PRIORITY_FLAG, :red) : ' '
234
252
  due_date = ''
235
253
  if task[:due] && state != 'done'
@@ -290,6 +308,17 @@ def colorize(text, color)
290
308
  "\e[#{COLOR_CODES[color]}m#{text}\e[0m"
291
309
  end
292
310
 
311
+ def convert_due_date(date = '')
312
+ due = nil
313
+ day_index = DUE_DATE_DAYS.index(date.to_s.downcase) || DUE_DATE_DAYS_SIMPLE.index(date.to_s.downcase)
314
+ if day_index
315
+ due = (TODAY.to_date + day_index).strftime(DATE_FORMAT)
316
+ else
317
+ due = date.nil? || date.empty? ? nil : Date.parse(date).strftime(DATE_FORMAT)
318
+ end
319
+ return due
320
+ end
321
+
293
322
  def read(arguments)
294
323
  begin
295
324
  action = arguments.first
@@ -299,17 +328,13 @@ def read(arguments)
299
328
  raise action + ' command requires at least one parameter' if args.nil? || args.empty?
300
329
  add(args.join(' '))
301
330
  when 'start'
302
- raise action + ' command can receive only one task number' if args.length > 1
303
- args.length == 1 ? change_state(args.first.to_i, 'started') : list(nil, [':started'])
331
+ args.length > 0 ? change_state(args.first.to_i, 'started', args[1..-1].join(' ')) : list(nil, [':started'])
304
332
  when 'done'
305
- raise action + ' command can receive only one task number' if args.length > 1
306
- args.length == 1 ? change_state(args.first.to_i, 'done') : list(nil, [':done'])
333
+ args.length > 0 ? change_state(args.first.to_i, 'done', args[1..-1].join(' ')) : list(nil, [':done'])
307
334
  when 'block'
308
- raise action + ' command can receive only one task number' if args.length > 1
309
- args.length == 1 ? change_state(args.first.to_i, 'blocked') : list(nil, [':blocked'])
335
+ args.length > 0 ? change_state(args.first.to_i, 'blocked', args[1..-1].join(' ')) : list(nil, [':blocked'])
310
336
  when 'reset'
311
- raise action + ' command can receive only one task number' if args.length > 1
312
- args.length == 1 ? change_state(args.first.to_i, 'new') : list(nil, [':new'])
337
+ args.length > 0 ? change_state(args.first.to_i, 'new', args[1..-1].join(' ')) : list(nil, [':new'])
313
338
  when 'prio'
314
339
  raise action + ' command requires exactly one parameter' if args.length != 1
315
340
  set_priority(args.first.to_i)
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.11
4
+ version: 0.1.12
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-02-10 00:00:00.000000000 Z
11
+ date: 2021-02-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: