doing 1.0.84 → 1.0.88

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c11e6c75768b8dc2db3a36c5cdd572ad03eb884e118848ebbe413df2988a53df
4
- data.tar.gz: a3f45b396e4c6b06bab65d24007f0437e72687c6811f559ece8f6c5ca2e7bbba
3
+ metadata.gz: cd3101f8217fd3af3a0aa5fa57b2b7daf72aeb15510f83a361971403338c293e
4
+ data.tar.gz: 9bfc051f1129c40db87ac8c31a1eb88d0e9f1b1bc96b6f697e42fdb5351e3d35
5
5
  SHA512:
6
- metadata.gz: 7be6844f9f6caa072014afeded310cbaddf2a15380fde5498aea0f980dd5e8448ca44f5c5d9692a2075818f632bbbd19cce93e0db338c621a487abed8259f555
7
- data.tar.gz: d0af857fee4113e2055af031059901b56e2ff94e849f9d3a0d167d8edde0519e4d6a6ebdeef55050ee313ed628ba6fa2fbd17e73cfc66143e57e7a2c42f93c8f
6
+ metadata.gz: 3f7f0fe38daa1f63757dd4b3fb9b6c8a8d55415d47d74c58b2f4450327954381020279e353a44a790142da3802ffc2f6ce1b828ace7fbf3b0042a050674b7084
7
+ data.tar.gz: c36980be8fb2b8ae10fa750965eb2faa0c3ba4a0230e2e68a12cf09195b4fa16e70851521e0437d5e744fd954b9d1f50b39e7e31c6704592d03d51786be80a99
data/README.md CHANGED
@@ -27,7 +27,7 @@ If there's something I want to look at later but doesn't need to be added to a t
27
27
 
28
28
  ## Installation
29
29
 
30
- The current version of `doing` is <!--VER-->1.0.83<!--END VER-->.
30
+ The current version of `doing` is <!--VER-->1.0.87<!--END VER-->.
31
31
 
32
32
  $ [sudo] gem install doing
33
33
 
@@ -92,6 +92,7 @@ A basic configuration looks like this:
92
92
  date_format: '%_I:%M%P'
93
93
  template: '%date > %title%odnote'
94
94
  wrap_width: 50
95
+ count: 10
95
96
  autotag:
96
97
  whitelist:
97
98
  - coding
@@ -239,6 +240,8 @@ and output my recent entries like this:
239
240
 
240
241
  $
241
242
 
243
+ The recent template can include a `count` key to specify the number of entries shown when run without an argument. Default is 10.
244
+
242
245
  ### Custom views
243
246
 
244
247
  You can create your own "views" in the `~/.doingrc` file and view them with `doing view view_name`. Just add a section like this:
@@ -542,6 +545,8 @@ If you have a use for it, you can use `-o csv` on the show or view commands to o
542
545
 
543
546
  `doing yesterday` is great for stand-ups (thanks to [Sean Collins](https://github.com/sc68cal) for that!). Note that you can show yesterday's activity from an alternate section by using the section name as an argument (e.g. `doing yesterday archive`).
544
547
 
548
+ All of the display commands (view, show, today, yesterday, search) support date ranges in addition to other filtering options. Results can be narrowed to a date/time span using `--before DATE` and `--after DATE`. The `DATE` accepts a natural language string but works best in formats like `10/20/21` or `2021-05-13 3pm` (or shortened to just `5/13 3pm`). For the `today` and `yesterday` commands the `DATE` should just be a time, e.g. `12pm` or `15:00`, and results will be filtered within the timespan for just that day. Both flags are optional, and you can use just `--before` to get everything older than a certain date, or use just `--after` to get everything newer.
549
+
545
550
  `doing on` allows for full date ranges and filtering. `doing on saturday`, or `doing on one month to today` will give you ranges. You can use the same terms with the `show` command by adding the `-f` or `--from` flag. `doing show @done --from "monday to friday"` will give you all of your completed items for the last week (assuming it's the weekend). There's also `doing since` a simple alias for `doing on PAST_DATE to now`, e.g. `doing since monday`.
546
551
 
547
552
  You can also show entries matching a search string with `doing grep` (synonym `doing search`). If you want to search with regular expressions or for an exact match, surround your search query with forward slashes, e.g. `doing search /project name/`. If you pass a search string without slashes, it's treated as a fuzzy search string, meaning matches can be found as long as the characters in the search string are in order and with no more than three other characters between each. By default searches are across all sections, but you can limit it to one with the `-s SECTION_NAME` flag. Searches can be displayed with the default template, or output as HTML, CSV, or JSON.
data/bin/doing CHANGED
@@ -333,10 +333,6 @@ command :later do |c|
333
333
  c.desc "Edit entry with #{ENV['EDITOR']}"
334
334
  c.switch %i[e editor], negatable: false, default_value: false
335
335
 
336
- c.desc 'Edit entry with specified app'
337
- c.arg_name 'APP'
338
- c.flag %i[a app]
339
-
340
336
  c.desc 'Backdate start time to date string [4pm|20m|2h|yesterday noon]'
341
337
  c.arg_name 'DATE_STRING'
342
338
  c.flag %i[b back]
@@ -353,7 +349,7 @@ command :later do |c|
353
349
  date = Time.now
354
350
  end
355
351
 
356
- if options[:e] || (args.empty? && $stdin.stat.size.zero?)
352
+ if options[:editor] || (args.empty? && $stdin.stat.size.zero?)
357
353
  exit_now! 'No EDITOR variable defined in environment' if ENV['EDITOR'].nil?
358
354
 
359
355
  input = args.empty? ? '' : args.join(' ')
@@ -456,7 +452,7 @@ command %i[done did] do |c|
456
452
  section = wwid.config['current_section']
457
453
  end
458
454
 
459
- if options[:e]
455
+ if options[:editor]
460
456
  exit_now! 'No EDITOR variable defined in environment' if ENV['EDITOR'].nil?
461
457
 
462
458
  input = ''
@@ -900,10 +896,22 @@ command :show do |c|
900
896
  c.arg_name 'MAX'
901
897
  c.flag %i[c count], default_value: 0
902
898
 
903
- c.desc 'Age (oldest/newest)'
899
+ c.desc 'Age (oldest|newest)'
904
900
  c.arg_name 'AGE'
905
901
  c.flag %i[a age], default_value: 'newest'
906
902
 
903
+ c.desc 'View entries older than date'
904
+ c.arg_name 'DATE_STRING'
905
+ c.flag [:before]
906
+
907
+ c.desc 'View entries newer than date'
908
+ c.arg_name 'DATE_STRING'
909
+ c.flag [:after]
910
+
911
+ c.desc 'Search filter, surround with slashes for regex (/query/)'
912
+ c.arg_name 'QUERY'
913
+ c.flag [:search]
914
+
907
915
  c.desc 'Sort order (asc/desc)'
908
916
  c.arg_name 'ORDER'
909
917
  c.flag %i[s sort], must_match: /^[ad].*/i, default_value: 'ASC'
@@ -928,6 +936,10 @@ command :show do |c|
928
936
  c.arg_name 'KEY'
929
937
  c.flag [:tag_sort], must_match: /^(?:name|time)/i, default_value: default
930
938
 
939
+ c.desc 'Tag sort direction (asc|desc)'
940
+ c.arg_name 'DIRECTION'
941
+ c.flag [:tag_order], must_match: /^(?:a(?:sc)?|d(?:esc)?)$/i
942
+
931
943
  c.desc 'Only show items with recorded time intervals'
932
944
  c.switch [:only_timed], default_value: false, negatable: false
933
945
 
@@ -983,8 +995,8 @@ command :show do |c|
983
995
  }
984
996
  end
985
997
 
986
- if options[:f]
987
- date_string = options[:f]
998
+ if options[:from]
999
+ date_string = options[:from]
988
1000
  if date_string =~ / (to|through|thru|(un)?til|-+) /
989
1001
  dates = date_string.split(/ (to|through|thru|(un)?til|-+) /)
990
1002
  start = wwid.chronify(dates[0])
@@ -997,22 +1009,31 @@ command :show do |c|
997
1009
  dates = [start, finish]
998
1010
  end
999
1011
 
1000
- options[:t] = true if options[:totals]
1012
+ options[:times] = true if options[:totals]
1001
1013
 
1002
1014
  tags_color = wwid.config.key?('tags_color') ? wwid.config['tags_color'] : nil
1003
1015
 
1004
1016
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1017
+ tag_order = if options[:tag_order]
1018
+ options[:tag_order] =~ /^d/i ? 'desc' : 'asc'
1019
+ else
1020
+ 'asc'
1021
+ end
1005
1022
  opts = {
1006
- age: options[:a],
1023
+ after: options[:after],
1024
+ age: options[:age],
1025
+ before: options[:before],
1007
1026
  count: options[:c].to_i,
1008
1027
  date_filter: dates,
1009
1028
  highlight: true,
1010
1029
  only_timed: options[:only_timed],
1011
1030
  order: options[:s],
1012
1031
  output: options[:output],
1032
+ search: options[:search],
1013
1033
  section: section,
1014
1034
  sort_tags: options[:sort_tags],
1015
1035
  tag_filter: tag_filter,
1036
+ tag_order: tag_order,
1016
1037
  tags_color: tags_color,
1017
1038
  times: options[:t],
1018
1039
  totals: options[:totals]
@@ -1034,6 +1055,14 @@ command [:grep, :search] do |c|
1034
1055
  c.arg_name 'NAME'
1035
1056
  c.flag %i[s section], default_value: 'All'
1036
1057
 
1058
+ c.desc 'Constrain search to entries older than date'
1059
+ c.arg_name 'DATE_STRING'
1060
+ c.flag [:before]
1061
+
1062
+ c.desc 'Constrain search to entries newer than date'
1063
+ c.arg_name 'DATE_STRING'
1064
+ c.flag [:after]
1065
+
1037
1066
  c.desc 'Output to export format (csv|html|json|template|timeline)'
1038
1067
  c.arg_name 'FORMAT'
1039
1068
  c.flag %i[o output], must_match: /^(?:template|html|csv|json|timeline)$/i
@@ -1058,10 +1087,12 @@ command [:grep, :search] do |c|
1058
1087
 
1059
1088
  section = wwid.guess_section(options[:s]) if options[:s]
1060
1089
 
1061
- options[:t] = true if options[:totals]
1090
+ options[:times] = true if options[:totals]
1062
1091
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1063
1092
 
1064
1093
  opts = {
1094
+ after: options[:after],
1095
+ before: options[:before],
1065
1096
  highlight: true,
1066
1097
  only_timed: options[:only_timed],
1067
1098
  output: options[:output],
@@ -1069,7 +1100,7 @@ command [:grep, :search] do |c|
1069
1100
  section: section,
1070
1101
  sort_tags: options[:sort_tags],
1071
1102
  tags_color: tags_color,
1072
- times: options[:t],
1103
+ times: options[:times],
1073
1104
  totals: options[:totals]
1074
1105
  }
1075
1106
 
@@ -1101,7 +1132,12 @@ command :recent do |c|
1101
1132
  section = wwid.guess_section(options[:s]) || options[:s].cap_first
1102
1133
 
1103
1134
  unless global_options[:version]
1104
- count = args.empty? ? 10 : args[0].to_i
1135
+ if wwid.config['templates']['recent'].key?('count')
1136
+ config_count = wwid.config['templates']['recent']['count'].to_i
1137
+ else
1138
+ config_count = 10
1139
+ end
1140
+ count = args.empty? ? config_count : args[0].to_i
1105
1141
  options[:t] = true if options[:totals]
1106
1142
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1107
1143
  tags_color = wwid.config.key?('tags_color') ? wwid.config['tags_color'] : nil
@@ -1141,12 +1177,25 @@ command :today do |c|
1141
1177
  c.arg_name 'FORMAT'
1142
1178
  c.flag %i[o output], must_match: /^(?:template|html|csv|json|timeline)$/i
1143
1179
 
1180
+ c.desc 'View entries before specified time (e.g. 8am, 12:30pm, 15:00)'
1181
+ c.arg_name 'TIME_STRING'
1182
+ c.flag [:before]
1183
+
1184
+ c.desc 'View entries after specified time (e.g. 8am, 12:30pm, 15:00)'
1185
+ c.arg_name 'TIME_STRING'
1186
+ c.flag [:after]
1187
+
1144
1188
  c.action do |_global_options, options, _args|
1145
1189
  options[:t] = true if options[:totals]
1146
1190
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1147
-
1148
- puts wwid.today(options[:t], options[:output],
1149
- { totals: options[:totals], section: options[:s], sort_tags: options[:sort_tags] }).chomp
1191
+ opt = {
1192
+ after: options[:after],
1193
+ before: options[:before],
1194
+ section: options[:section],
1195
+ sort_tags: options[:sort_tags],
1196
+ totals: options[:totals]
1197
+ }
1198
+ puts wwid.today(options[:times], options[:output], opt).chomp
1150
1199
  end
1151
1200
  end
1152
1201
 
@@ -1275,10 +1324,33 @@ command :yesterday do |c|
1275
1324
  c.arg_name 'KEY'
1276
1325
  c.flag [:tag_sort], must_match: /^(?:name|time)$/i, default_value: default
1277
1326
 
1327
+ c.desc 'View entries before specified time (e.g. 8am, 12:30pm, 15:00)'
1328
+ c.arg_name 'TIME_STRING'
1329
+ c.flag [:before]
1330
+
1331
+ c.desc 'View entries after specified time (e.g. 8am, 12:30pm, 15:00)'
1332
+ c.arg_name 'TIME_STRING'
1333
+ c.flag [:after]
1334
+
1335
+ c.desc 'Tag sort direction (asc|desc)'
1336
+ c.arg_name 'DIRECTION'
1337
+ c.flag [:tag_order], must_match: /^(?:a(?:sc)?|d(?:esc)?)$/i
1338
+
1278
1339
  c.action do |_global_options, options, _args|
1340
+ tag_order = if options[:tag_order]
1341
+ options[:tag_order] =~ /^d/i ? 'desc' : 'asc'
1342
+ else
1343
+ 'asc'
1344
+ end
1279
1345
  options[:sort_tags] = options[:tag_sort] =~ /^n/i
1280
- puts wwid.yesterday(options[:s], options[:t], options[:o],
1281
- { totals: options[:totals], sort_tags: options[:sort_tags] }).chomp
1346
+ opt = {
1347
+ after: options[:after],
1348
+ before: options[:before],
1349
+ sort_tags: options[:sort_tags],
1350
+ tag_order: options[:tag_order],
1351
+ totals: options[:totals]
1352
+ }
1353
+ puts wwid.yesterday(options[:section], options[:times], options[:output], opt).chomp
1282
1354
  end
1283
1355
  end
1284
1356
 
@@ -1321,7 +1393,7 @@ command :last do |c|
1321
1393
 
1322
1394
  end
1323
1395
 
1324
- if options[:e]
1396
+ if options[:editor]
1325
1397
  wwid.edit_last(section: options[:s], options: { search: options[:search], tag: tags, tag_bool: options[:bool] })
1326
1398
  else
1327
1399
  puts wwid.last(times: true, section: options[:s],
@@ -1380,7 +1452,7 @@ command :colors do |c|
1380
1452
  end
1381
1453
 
1382
1454
  desc 'Display a user-created view'
1383
- long_desc 'Command line options override associated view settings'
1455
+ long_desc 'Command line options override view configuration'
1384
1456
  arg_name 'VIEW_NAME'
1385
1457
  command :view do |c|
1386
1458
  c.desc 'Section'
@@ -1404,6 +1476,18 @@ command :view do |c|
1404
1476
  c.desc 'Include colors in output'
1405
1477
  c.switch [:color], default_value: true, negatable: true
1406
1478
 
1479
+ c.desc 'Tag filter, combine multiple tags with a comma.'
1480
+ c.arg_name 'TAG'
1481
+ c.flag [:tag]
1482
+
1483
+ c.desc 'Tag boolean (AND,OR,NOT)'
1484
+ c.arg_name 'BOOLEAN'
1485
+ c.flag %i[b bool], must_match: /(?:and|all|any|or|not|none)/i, default_value: 'OR'
1486
+
1487
+ c.desc 'Search filter, surround with slashes for regex (/query/)'
1488
+ c.arg_name 'QUERY'
1489
+ c.flag [:search]
1490
+
1407
1491
  c.desc 'Sort tags by (name|time)'
1408
1492
  c.arg_name 'KEY'
1409
1493
  c.flag [:tag_sort], must_match: /^(?:name|time)$/i
@@ -1412,10 +1496,20 @@ command :view do |c|
1412
1496
  c.arg_name 'DIRECTION'
1413
1497
  c.flag [:tag_order], must_match: /^(?:a(?:sc)?|d(?:esc)?)$/i
1414
1498
 
1499
+ c.desc 'View entries older than date'
1500
+ c.arg_name 'DATE_STRING'
1501
+ c.flag [:before]
1502
+
1503
+ c.desc 'View entries newer than date'
1504
+ c.arg_name 'DATE_STRING'
1505
+ c.flag [:after]
1506
+
1415
1507
  c.desc 'Only show items with recorded time intervals (override view settings)'
1416
1508
  c.switch [:only_timed], default_value: false, negatable: false
1417
1509
 
1418
1510
  c.action do |_global_options, options, args|
1511
+ exit_now! '--tag and --search cannot be used together' if options[:tag] && options[:search]
1512
+
1419
1513
  title = if args.empty?
1420
1514
  wwid.choose_view
1421
1515
  else
@@ -1440,7 +1534,11 @@ command :view do |c|
1440
1534
  format = view.key?('date_format') ? view['date_format'] : nil
1441
1535
  tags_color = view.key?('tags_color') ? view['tags_color'] : nil
1442
1536
  tag_filter = false
1443
- if view.key?('tags') && !(view['tags'].nil? || view['tags'].empty?)
1537
+ if options[:tag]
1538
+ tag_filter = { 'tags' => [], 'bool' => 'OR' }
1539
+ tag_filter['tags'] = options[:tag].gsub(/[, ]+/, ' ').split(' ').map(&:strip)
1540
+ tag_filter['bool'] = options[:bool].normalize_bool
1541
+ elsif view.key?('tags') && !(view['tags'].nil? || view['tags'].empty?)
1444
1542
  tag_filter = { 'tags' => [], 'bool' => 'OR' }
1445
1543
  tag_filter['tags'] = if view['tags'].instance_of?(Array)
1446
1544
  view['tags'].map(&:strip)
@@ -1489,14 +1587,17 @@ command :view do |c|
1489
1587
  else
1490
1588
  'asc'
1491
1589
  end
1492
- warn "TAG ORDER: #{options[:tag_order]}"
1590
+
1493
1591
  opts = {
1592
+ after: options[:after],
1593
+ before: options[:before],
1494
1594
  count: count,
1495
1595
  format: format,
1496
1596
  highlight: options[:color],
1497
1597
  only_timed: only_timed,
1498
1598
  order: order,
1499
- output: options[:o],
1599
+ output: options[:output],
1600
+ search: options[:search],
1500
1601
  section: section,
1501
1602
  sort_tags: options[:sort_tags],
1502
1603
  tag_filter: tag_filter,
@@ -1554,6 +1655,11 @@ command :archive do |c|
1554
1655
  c.arg_name 'QUERY'
1555
1656
  c.flag [:search]
1556
1657
 
1658
+ c.desc 'Archive entries older than date
1659
+ (Flexible date format, e.g. 1/27/2021, 2020-07-19, or Monday 3pm)'
1660
+ c.arg_name 'DATE_STRING'
1661
+ c.flag [:before]
1662
+
1557
1663
  c.action do |_global_options, options, args|
1558
1664
  if args.empty?
1559
1665
  section = wwid.current_section
@@ -1583,6 +1689,7 @@ command :archive do |c|
1583
1689
  'AND'
1584
1690
  end
1585
1691
  opts = {
1692
+ before: options[:before],
1586
1693
  bool: options[:bool],
1587
1694
  destination: options[:to],
1588
1695
  keep: options[:keep],
@@ -1615,6 +1722,11 @@ command :rotate do |c|
1615
1722
  c.arg_name 'QUERY'
1616
1723
  c.flag [:search]
1617
1724
 
1725
+ c.desc 'Rotate entries older than date
1726
+ (Flexible date format, e.g. 1/27/2021, 2020-07-19, or Monday 3pm)'
1727
+ c.arg_name 'DATE_STRING'
1728
+ c.flag [:before]
1729
+
1618
1730
  c.action do |_global_options, options, args|
1619
1731
  if options[:section] && options[:section] !~ /^all$/i
1620
1732
  options[:section] = wwid.guess_section(options[:section])
@@ -1641,11 +1753,11 @@ command :open do |c|
1641
1753
  if `uname` =~ /Darwin/
1642
1754
  c.desc 'Open with app name'
1643
1755
  c.arg_name 'APP_NAME'
1644
- c.flag [:a]
1756
+ c.flag %i[a app]
1645
1757
 
1646
1758
  c.desc 'Open with app bundle id'
1647
1759
  c.arg_name 'BUNDLE_ID'
1648
- c.flag [:b]
1760
+ c.flag %i[b bundle_id]
1649
1761
  end
1650
1762
  c.desc "Open with $EDITOR (#{ENV['EDITOR']})"
1651
1763
  c.switch %i[e editor], negatable: false, default_value: false
@@ -1656,11 +1768,11 @@ command :open do |c|
1656
1768
  k.instance_of?(String) || v.nil? || v == false
1657
1769
  end
1658
1770
  if `uname` =~ /Darwin/
1659
- if options[:a]
1771
+ if options[:app]
1660
1772
  system %(open -a "#{options[:a]}" "#{File.expand_path(wwid.doing_file)}")
1661
- elsif options[:b]
1773
+ elsif options[:bundle_id]
1662
1774
  system %(open -b "#{options[:b]}" "#{File.expand_path(wwid.doing_file)}")
1663
- elsif options[:e]
1775
+ elsif options[:editor]
1664
1776
  exit_now! 'No EDITOR variable defined in environment' if ENV['EDITOR'].nil?
1665
1777
 
1666
1778
  system %($EDITOR "#{File.expand_path(wwid.doing_file)}")
data/lib/doing/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Doing
2
- VERSION = '1.0.84'
2
+ VERSION = '1.0.88'
3
3
  end
data/lib/doing/wwid.rb CHANGED
@@ -124,7 +124,8 @@ class WWID
124
124
  @config['templates']['recent'] ||= {
125
125
  'date_format' => '%_I:%M%P',
126
126
  'template' => '%shortdate: %title (%section)',
127
- 'wrap_width' => 88
127
+ 'wrap_width' => 88,
128
+ 'count' => 10
128
129
  }
129
130
  @config['views'] ||= {
130
131
  'done' => {
@@ -1100,7 +1101,6 @@ class WWID
1100
1101
  items = @content[section]['items'].dup.sort_by { |item| item['date'] }.reverse
1101
1102
  idx = 0
1102
1103
  done_date = Time.now
1103
- next_start = Time.now
1104
1104
  count = (opt[:count]).zero? ? items.length : opt[:count]
1105
1105
  items.map! do |item|
1106
1106
  break if idx == count
@@ -1119,8 +1119,8 @@ class WWID
1119
1119
  end
1120
1120
  else
1121
1121
  if opt[:sequential]
1122
- done_date = next_start - 1
1123
- next_start = item['date']
1122
+ next_entry = next_item(item)
1123
+ done_date = next_entry['date'] - 60 if next_entry
1124
1124
  elsif opt[:took]
1125
1125
  if item['date'] + opt[:took] > Time.now
1126
1126
  item['date'] = Time.now - opt[:took]
@@ -1209,6 +1209,24 @@ class WWID
1209
1209
  return new_item
1210
1210
  end
1211
1211
 
1212
+ ##
1213
+ ## @brief Get next item in the index
1214
+ ##
1215
+ ## @param old_item
1216
+ ##
1217
+ def next_item(old_item)
1218
+ section = old_item['section']
1219
+
1220
+ section_items = @content[section]['items'].sort_by { |entry| entry['date'] }
1221
+ idx = section_items.index(old_item)
1222
+
1223
+ if section_items.size > idx
1224
+ section_items[idx + 1]
1225
+ else
1226
+ nil
1227
+ end
1228
+ end
1229
+
1212
1230
  ##
1213
1231
  ## @brief Delete an item from the index
1214
1232
  ##
@@ -1478,7 +1496,7 @@ class WWID
1478
1496
  ##
1479
1497
  ## @param file (String) The filepath to write to
1480
1498
  ##
1481
- def write(file = nil)
1499
+ def write(file = nil, backup: true)
1482
1500
  output = @other_content_top ? "#{@other_content_top.join("\n")}\n" : ''
1483
1501
 
1484
1502
  @content.each do |title, section|
@@ -1490,7 +1508,7 @@ class WWID
1490
1508
  $stdout.puts output
1491
1509
  else
1492
1510
  file = File.expand_path(file)
1493
- if File.exist?(file)
1511
+ if File.exist?(file) && backup
1494
1512
  # Create a backup copy for the undo command
1495
1513
  FileUtils.cp(file, "#{file}~")
1496
1514
  end
@@ -1549,9 +1567,15 @@ class WWID
1549
1567
  new_content[section]['items'] = []
1550
1568
 
1551
1569
  moved_items = []
1552
- if !tags.empty? || opt[:search]
1570
+ if !tags.empty? || opt[:search] || opt[:before]
1571
+ if opt[:before]
1572
+ time_string = opt[:before]
1573
+ time_string += ' 12am' if time_string !~ /(\d+:\d+|\d+[ap])/
1574
+ cutoff = chronify(time_string)
1575
+ end
1576
+
1553
1577
  items.delete_if do |item|
1554
- if ((!tags.empty? && item.has_tags?(tags, bool)) || (opt[:search] && item.matches_search?(opt[:search].to_s)))
1578
+ if ((!tags.empty? && item.has_tags?(tags, bool)) || (opt[:search] && item.matches_search?(opt[:search].to_s)) || (opt[:before] && item['date'] < cutoff))
1555
1579
  moved_items.push(item)
1556
1580
  counter += 1
1557
1581
  true
@@ -1587,10 +1611,15 @@ class WWID
1587
1611
 
1588
1612
  write(@doing_file)
1589
1613
 
1590
- file = @doing_file.sub(/(\.\w+)$/, "_#{Time.now.strftime('%Y-%m-%d%H:%M')}\\1")
1591
- @content = new_content
1614
+ file = @doing_file.sub(/(\.\w+)$/, "_#{Time.now.strftime('%Y-%m-%d')}\\1")
1615
+ if File.exist?(file)
1616
+ init_doing_file(file)
1617
+ @content.deep_merge(new_content)
1618
+ else
1619
+ @content = new_content
1620
+ end
1592
1621
 
1593
- write(file)
1622
+ write(file, backup: false)
1594
1623
  end
1595
1624
 
1596
1625
  ##
@@ -1713,6 +1742,24 @@ class WWID
1713
1742
  end
1714
1743
  end
1715
1744
 
1745
+ if opt[:before]
1746
+ time_string = opt[:before]
1747
+ time_string += ' 12am' if time_string !~ /(\d+:\d+|\d+[ap])/
1748
+ cutoff = chronify(time_string)
1749
+ if cutoff
1750
+ items.delete_if { |item| item['date'] >= cutoff }
1751
+ end
1752
+ end
1753
+
1754
+ if opt[:after]
1755
+ time_string = opt[:after]
1756
+ time_string += ' 11:59pm' if time_string !~ /(\d+:\d+|\d+[ap])/
1757
+ cutoff = chronify(time_string)
1758
+ if cutoff
1759
+ items.delete_if { |item| item['date'] <= cutoff }
1760
+ end
1761
+ end
1762
+
1716
1763
  if opt[:today]
1717
1764
  items.delete_if do |item|
1718
1765
  item['date'] < Date.today.to_time
@@ -1940,13 +1987,13 @@ class WWID
1940
1987
 
1941
1988
  output.sub!(/%shortdate/) do
1942
1989
  if item['date'] > Date.today.to_time
1943
- item['date'].strftime('%_I:%M%P')
1944
- elsif item['date'] > (Date.today - 7).to_time
1945
- item['date'].strftime('%a %-I:%M%P')
1990
+ item['date'].strftime(' %_I:%M%P')
1991
+ elsif item['date'] > (Date.today - 6).to_time
1992
+ item['date'].strftime('%a %_I:%M%P')
1946
1993
  elsif item['date'].year == Date.today.year
1947
- item['date'].strftime('%b %d, %-I:%M%P')
1994
+ item['date'].strftime('%m/%d %_I:%M%P')
1948
1995
  else
1949
- item['date'].strftime('%b %d %Y, %-I:%M%P')
1996
+ item['date'].strftime('%m/%d/%Y %_I:%M%P')
1950
1997
  end
1951
1998
  end
1952
1999
 
@@ -2012,7 +2059,7 @@ class WWID
2012
2059
  destination = guess_section(destination)
2013
2060
 
2014
2061
  if sections.include?(destination) && (sections.include?(section) || archive_all)
2015
- do_archive(section, destination, { count: count, tags: tags, bool: bool, search: options[:search], label: options[:label] })
2062
+ do_archive(section, destination, { count: count, tags: tags, bool: bool, search: options[:search], label: options[:label], before: options[:before] })
2016
2063
  write(doing_file)
2017
2064
  else
2018
2065
  exit_now! 'Either source or destination does not exist'
@@ -2045,9 +2092,15 @@ class WWID
2045
2092
  items = @content[section]['items'].dup
2046
2093
 
2047
2094
  moved_items = []
2048
- if !tags.empty? || opt[:search]
2095
+ if !tags.empty? || opt[:search] || opt[:before]
2096
+ if opt[:before]
2097
+ time_string = opt[:before]
2098
+ time_string += ' 12am' if time_string !~ /(\d+:\d+|\d+[ap])/
2099
+ cutoff = chronify(time_string)
2100
+ end
2101
+
2049
2102
  items.delete_if do |item|
2050
- if (!tags.empty? && item.has_tags?(tags, bool) || (opt[:search] && item.matches_search?(opt[:search].to_s)))
2103
+ if ((!tags.empty? && item.has_tags?(tags, bool)) || (opt[:search] && item.matches_search?(opt[:search].to_s)) || (opt[:before] && item['date'] < cutoff))
2051
2104
  moved_items.push(item)
2052
2105
  counter += 1
2053
2106
  true
@@ -2154,8 +2207,22 @@ class WWID
2154
2207
  opt[:sort_tags] ||= false
2155
2208
 
2156
2209
  cfg = @config['templates']['today']
2157
- list_section({ section: opt[:section], wrap_width: cfg['wrap_width'], count: 0,
2158
- format: cfg['date_format'], template: cfg['template'], order: 'asc', today: true, times: times, output: output, totals: opt[:totals], sort_tags: opt[:sort_tags] })
2210
+ options = {
2211
+ after: opt[:after],
2212
+ before: opt[:before],
2213
+ count: 0,
2214
+ format: cfg['date_format'],
2215
+ order: 'asc',
2216
+ output: output,
2217
+ section: opt[:section],
2218
+ sort_tags: opt[:sort_tags],
2219
+ template: cfg['template'],
2220
+ times: times,
2221
+ today: true,
2222
+ totals: opt[:totals],
2223
+ wrap_width: cfg['wrap_width']
2224
+ }
2225
+ list_section(options)
2159
2226
  end
2160
2227
 
2161
2228
  ##
@@ -2190,8 +2257,25 @@ class WWID
2190
2257
  opt[:totals] ||= false
2191
2258
  opt[:sort_tags] ||= false
2192
2259
  section = guess_section(section)
2193
- list_section({ section: section, count: 0, order: 'asc', yesterday: true, times: times,
2194
- output: output, totals: opt[:totals], sort_tags: opt[:sort_tags] })
2260
+ y = (Time.now - (60 * 60 * 24)).strftime('%Y-%m-%d')
2261
+ opt[:after] = "#{y} #{opt[:after]}" if opt[:after]
2262
+ opt[:before] = "#{y} #{opt[:before]}" if opt[:before]
2263
+
2264
+ options = {
2265
+ after: opt[:after],
2266
+ before: opt[:before],
2267
+ count: 0,
2268
+ order: 'asc',
2269
+ output: output,
2270
+ section: section,
2271
+ sort_tags: opt[:sort_tags],
2272
+ tag_order: opt[:tag_order],
2273
+ times: times,
2274
+ totals: opt[:totals],
2275
+ yesterday: true
2276
+ }
2277
+
2278
+ list_section(options)
2195
2279
  end
2196
2280
 
2197
2281
  ##
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.84
4
+ version: 1.0.88
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra