doing 1.0.38 → 1.0.43

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: 9638a33587192a9a5146ace1e3d8e6937efb34922b7b93c71ba088880f136ed4
4
- data.tar.gz: 07bc825013ac19e6b4a1b4ef3103ac0f04ce186575ec65c724e55664b74087d6
3
+ metadata.gz: fa5febc2d54f2d65e4e09b1b72e65cd19c3ca19c2c5b7b155fae667071f77aeb
4
+ data.tar.gz: 1a8401a27918d5e1ec4b5b66ae6986e2130a3dde568f894c79e93b8b610ed8cb
5
5
  SHA512:
6
- metadata.gz: '087fa6df46f96bb25ddb7904505e10669a5bb28104e0652b890a497067ed8255ec2d6ce9e3e54018372efdf86b7272bd4a81c09b1a93b99e8f90e09ed86af381'
7
- data.tar.gz: e395fd115d20f77cd522d086fa19b1bde92a51ea7785cf3f8b16ae39004f490ebc918be798d70e3ce133effcc15948c774493ddf84e541fd0b3a3e83271e0d90
6
+ metadata.gz: 558ee0d409f410ec30a15f5cf99194f1a9a6c98bc6d7711ccff5d8d88492166fd9d2ff12b3b3cf304fd3c393e975bb09cda92efadb6439db8d20fe12a7a9b882
7
+ data.tar.gz: 638222cb9655553bbd230262127ccb03b551bb03989ab58e2cfecb9908735a654e775203c379593e3b79cebef132fcb2f8bad1d8251e73836e9758e8e7e6988d
data/bin/doing CHANGED
@@ -488,6 +488,21 @@ command :finish do |c|
488
488
  end
489
489
  end
490
490
 
491
+ desc 'Repeat last entry as new entry'
492
+ arg_name 'section'
493
+ command [:again,:resume] do |c|
494
+ c.desc 'Section'
495
+ c.flag [:s, :section], :default_value => "All"
496
+
497
+ c.desc 'Note'
498
+ c.arg_name 'note_text'
499
+ c.flag [:n,:note]
500
+
501
+ c.action do |global_options, options, args|
502
+ wwid.restart_last({ section: options[:s], note: options[:n] })
503
+ end
504
+ end
505
+
491
506
  desc 'Tag last entry'
492
507
  arg_name 'tag1 [tag2...]'
493
508
  command :tag do |c|
@@ -555,7 +570,7 @@ command :tag do |c|
555
570
  end
556
571
 
557
572
  desc 'Mark last entry as highlighted'
558
- command :mark do |c|
573
+ command [:mark,:flag] do |c|
559
574
  c.desc 'Section'
560
575
  c.default_value wwid.current_section
561
576
  c.flag [:s,:section], :default_value => wwid.current_section
@@ -699,6 +714,13 @@ command [:grep,:search] do |c|
699
714
  c.default_value false
700
715
  c.switch [:totals], :default_value => false, :negatable => true
701
716
 
717
+ c.desc 'Sort tags by (name|time)'
718
+ default = 'time'
719
+ if wwid.config.has_key?('tag_sort')
720
+ default = wwid.config['tag_sort']
721
+ end
722
+ c.flag [:tag_sort], :default_value => default
723
+
702
724
  c.desc 'Only show items with recorded time intervals'
703
725
  c.default_value false
704
726
  c.switch [:only_timed], :default_value => false, :negatable => false
@@ -708,8 +730,9 @@ command [:grep,:search] do |c|
708
730
  section = wwid.guess_section(options[:s]) if options[:s]
709
731
 
710
732
  options[:t] = true if options[:totals]
733
+ options[:sort_tags] = options[:tag_sort] =~ /^n/i
711
734
 
712
- puts wwid.list_section({:search => args.join(' '), :section => section, :output => options[:output], :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => options[:only_timed]})
735
+ puts wwid.list_section({:search => args.join(' '), :section => section, :output => options[:output], :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => options[:only_timed], :sort_tags => options[:sort_tags]})
713
736
 
714
737
  end
715
738
  end
@@ -730,6 +753,13 @@ command :recent do |c|
730
753
  c.default_value false
731
754
  c.switch [:totals], :default_value => false, :negatable => true
732
755
 
756
+ c.desc 'Sort tags by (name|time)'
757
+ default = 'time'
758
+ if wwid.config.has_key?('tag_sort')
759
+ default = wwid.config['tag_sort']
760
+ end
761
+ c.flag [:tag_sort], :default_value => default
762
+
733
763
  c.action do |global_options,options,args|
734
764
 
735
765
  section = wwid.guess_section(options[:s]) || options[:s].cap_first
@@ -741,8 +771,9 @@ command :recent do |c|
741
771
  count = 10
742
772
  end
743
773
  options[:t] = true if options[:totals]
774
+ options[:sort_tags] = options[:tag_sort] =~ /^n/i
744
775
 
745
- puts wwid.recent(count,section.cap_first,{ :times => options[:t], :totals => options[:totals] })
776
+ puts wwid.recent(count,section.cap_first,{ :times => options[:t], :totals => options[:totals], :sort_tags => options[:sort_tags] })
746
777
 
747
778
  end
748
779
  end
@@ -763,14 +794,22 @@ command :today do |c|
763
794
  c.default_value false
764
795
  c.switch [:totals], :default_value => false, :negatable => true
765
796
 
797
+ c.desc 'Sort tags by (name|time)'
798
+ default = 'time'
799
+ if wwid.config.has_key?('tag_sort')
800
+ default = wwid.config['tag_sort']
801
+ end
802
+ c.flag [:tag_sort], :default_value => default
803
+
766
804
  c.desc 'Output to export format (csv|html|json)'
767
805
  c.flag [:o,:output]
768
806
 
769
807
  c.action do |global_options,options,args|
770
808
 
771
809
  options[:t] = true if options[:totals]
810
+ options[:sort_tags] = options[:tag_sort] =~ /^n/i
772
811
 
773
- puts wwid.today(options[:t],options[:output],{:totals => options[:totals], :section => options[:s]}).chomp
812
+ puts wwid.today(options[:t],options[:output],{:totals => options[:totals], :section => options[:s], :sort_tags => options[:sort_tags]}).chomp
774
813
 
775
814
  end
776
815
  end
@@ -792,6 +831,13 @@ command :on do |c|
792
831
  c.default_value false
793
832
  c.switch [:totals], :default_value => false, :negatable => true
794
833
 
834
+ c.desc 'Sort tags by (name|time)'
835
+ default = 'time'
836
+ if wwid.config.has_key?('tag_sort')
837
+ default = wwid.config['tag_sort']
838
+ end
839
+ c.flag [:tag_sort], :default_value => default
840
+
795
841
  c.desc 'Output to export format (csv|html|json)'
796
842
  c.flag [:o,:output]
797
843
 
@@ -815,8 +861,9 @@ command :on do |c|
815
861
  wwid.results.push(message)
816
862
 
817
863
  options[:t] = true if options[:totals]
864
+ options[:sort_tags] = options[:tag_sort] =~ /^n/i
818
865
 
819
- puts wwid.list_date([start,finish],options[:s],options[:t],options[:output],{:totals => options[:totals]}).chomp
866
+ puts wwid.list_date([start, finish], options[:s], options[:t], options[:output], {:totals => options[:totals], :sort_tags => options[:sort_tags]}).chomp
820
867
 
821
868
  end
822
869
  end
@@ -839,8 +886,16 @@ command :yesterday do |c|
839
886
  c.default_value false
840
887
  c.switch [:totals], :default_value => false, :negatable => true
841
888
 
889
+ c.desc 'Sort tags by (name|time)'
890
+ default = 'time'
891
+ if wwid.config.has_key?('tag_sort')
892
+ default = wwid.config['tag_sort']
893
+ end
894
+ c.flag [:tag_sort], :default_value => default
895
+
842
896
  c.action do |global_options, options,args|
843
- puts wwid.yesterday(options[:s],options[:t],options[:o],{:totals => options[:totals]}).chomp
897
+ options[:sort_tags] = options[:tag_sort] =~ /^n/i
898
+ puts wwid.yesterday(options[:s],options[:t],options[:o],{:totals => options[:totals], :sort_tags => options[:sort_tags]}).chomp
844
899
 
845
900
  end
846
901
  end
@@ -927,6 +982,13 @@ command :view do |c|
927
982
  c.default_value false
928
983
  c.switch [:totals], :default_value => false, :negatable => true
929
984
 
985
+ c.desc 'Sort tags by (name|time)'
986
+ default = 'time'
987
+ if wwid.config.has_key?('tag_sort')
988
+ default = wwid.config['tag_sort']
989
+ end
990
+ c.flag [:tag_sort], :default_value => default
991
+
930
992
  c.desc 'Only show items with recorded time intervals'
931
993
  c.default_value false
932
994
  c.switch [:only_timed], :default_value => false, :negatable => true
@@ -972,9 +1034,12 @@ command :view do |c|
972
1034
  count = options[:c] ? options[:c] : view.has_key?('count') ? view['count'] : 10
973
1035
  section = options[:s] ? section : view.has_key?('section') ? view['section'] : wwid.current_section
974
1036
  order = view.has_key?('order') ? view['order'] : "asc"
1037
+
975
1038
  options[:t] = true if options[:totals]
976
1039
  options[:output].downcase! if options[:output]
977
- puts wwid.list_section({:section => section, :count => count, :template => template, :format => format, :order => order, :tag_filter => tag_filter, :output => options[:o], :tags_color => tags_color, :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => only_timed })
1040
+ options[:sort_tags] = options[:tag_sort] =~ /^n/i
1041
+
1042
+ puts wwid.list_section({:section => section, :count => count, :template => template, :format => format, :order => order, :tag_filter => tag_filter, :output => options[:o], :tags_color => tags_color, :times => options[:t], :highlight => true, :totals => options[:totals], :only_timed => only_timed, :sort_tags => options[:sort_tags] })
978
1043
  else
979
1044
  if title.class == FalseClass
980
1045
  exit_now! "Cancelled"
@@ -1162,7 +1227,15 @@ post do |global,command,options,args|
1162
1227
  if global[:stdout]
1163
1228
  $stdout.print wwid.results.join("\n")
1164
1229
  else
1165
- $stderr.puts wwid.results.join("\n")
1230
+ warn wwid.results.join("\n")
1231
+ end
1232
+
1233
+ if wwid.config['run_after']
1234
+ script = File.expand_path(wwid.config['run_after'])
1235
+ if File.exist?(script)
1236
+ warn "Running #{script}"
1237
+ `#{script}`
1238
+ end
1166
1239
  end
1167
1240
  end
1168
1241
 
data/lib/doing/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Doing
2
- VERSION = '1.0.38'
2
+ VERSION = '1.0.43'
3
3
  end
data/lib/doing/wwid.rb CHANGED
@@ -654,6 +654,62 @@ class WWID
654
654
  end
655
655
  end
656
656
 
657
+ ##
658
+ ## @brief Restart the last entry
659
+ ##
660
+ ## @param opt (Hash) Additional Options
661
+ ##
662
+ def restart_last(opt = {})
663
+ opt[:section] ||= 'all'
664
+ opt[:note] ||= []
665
+
666
+ last = last_entry(opt)
667
+ if last.nil?
668
+ @results.push(%Q{No previous entry found})
669
+ return
670
+ end
671
+ # Remove @done tag
672
+ title = last['title'].sub!(/\s*@done(\(.*?\))?/, '').chomp
673
+ add_item(title, last['section'], {:note => opt[:note], :back => opt[:date], :timed => true})
674
+ write(@doing_file)
675
+ end
676
+
677
+ ##
678
+ ## @brief Get the last entry
679
+ ##
680
+ ## @param opt (Hash) Additional Options
681
+ ##
682
+ def last_entry(opt={})
683
+ opt[:section] ||= @current_section
684
+
685
+ sec_arr = []
686
+
687
+ if opt[:section].nil?
688
+ sec_arr = [@current_section]
689
+ elsif opt[:section].class == String
690
+ if opt[:section] =~ /^all$/i
691
+ combined = {'items' => []}
692
+ @content.each {|k,v|
693
+ combined['items'] += v['items']
694
+ }
695
+ items = combined['items'].dup.sort_by{|item| item['date'] }.reverse
696
+ sec_arr.push(items[0]['section'])
697
+
698
+ sec_arr = sections
699
+ else
700
+ sec_arr = [guess_section(opt[:section])]
701
+ end
702
+ end
703
+
704
+
705
+ all_items = []
706
+ sec_arr.each do |section|
707
+ all_items.concat(@content[section]['items'].dup) if @content.has_key?(section)
708
+ end
709
+
710
+ all_items.sort_by { |item| item['date'] }.last
711
+ end
712
+
657
713
  ##
658
714
  ## @brief Tag the last entry or X entries
659
715
  ##
@@ -1125,7 +1181,6 @@ class WWID
1125
1181
  }
1126
1182
  out = output.join("")
1127
1183
  elsif opt[:output] == "json" || opt[:output] == "timeline"
1128
-
1129
1184
  items_out = []
1130
1185
  max = items[-1]['date'].strftime('%F')
1131
1186
  min = items[0]['date'].strftime('%F')
@@ -1137,7 +1192,6 @@ class WWID
1137
1192
  title = i['title']
1138
1193
  note = i['note'].map { |line| line.strip } if i['note']
1139
1194
  end
1140
-
1141
1195
  if i['title'] =~ /@done\((\d{4}-\d\d-\d\d \d\d:\d\d.*?)\)/ && opt[:times]
1142
1196
  end_date = Time.parse($1)
1143
1197
  interval = get_interval(i,false)
@@ -1152,14 +1206,16 @@ class WWID
1152
1206
  tags.push(tag[0]) unless skip_tags.include?(tag[0])
1153
1207
  }
1154
1208
  if opt[:output] == "json"
1209
+
1155
1210
  items_out << {
1156
1211
  :date => i['date'],
1157
1212
  :end_date => end_date,
1158
1213
  :title => title.strip, #+ " #{note}"
1159
- :note => note.class == Array ? note.join("\n") : note,
1214
+ :note => note.class == Array ? note.map(&:strip).join("\n") : note,
1160
1215
  :time => "%02d:%02d:%02d" % fmt_time(interval),
1161
1216
  :tags => tags
1162
1217
  }
1218
+
1163
1219
  elsif opt[:output] == "timeline"
1164
1220
  new_item = {
1165
1221
  'id' => index + 1,
@@ -1280,7 +1336,7 @@ EOTEMPLATE
1280
1336
  end
1281
1337
 
1282
1338
  if (item.has_key?('note') && !item['note'].empty?) && @config[:include_notes]
1283
- note_lines = item['note'].delete_if{|line| line =~ /^\s*$/ }.map{|line| "\t" + line.sub(/^\t*/,'') + " " }
1339
+ note_lines = item['note'].delete_if{|line| line =~ /^\s*$/ }.map{|line| "\t\t" + line.sub(/^\t*/,'').sub(/^-/, '—') + " " }
1284
1340
  if opt[:wrap_width] && opt[:wrap_width] > 0
1285
1341
  width = opt[:wrap_width]
1286
1342
  note_lines.map! {|line|
@@ -1528,8 +1584,10 @@ EOTEMPLATE
1528
1584
  ##
1529
1585
  def today(times=true,output=nil,opt={})
1530
1586
  opt[:totals] ||= false
1587
+ opt[:sort_tags] ||= false
1588
+
1531
1589
  cfg = @config['templates']['today']
1532
- list_section({:section => opt[:section], :wrap_width => cfg['wrap_width'], :count => 0, :format => cfg['date_format'], :template => cfg['template'], :order => "asc", :today => true, :times => times, :output => output, :totals => opt[:totals]})
1590
+ list_section({:section => opt[:section], :wrap_width => cfg['wrap_width'], :count => 0, :format => cfg['date_format'], :template => cfg['template'], :order => "asc", :today => true, :times => times, :output => output, :totals => opt[:totals], :sort_tags => opt[:sort_tags]})
1533
1591
  end
1534
1592
 
1535
1593
  ##
@@ -1543,13 +1601,14 @@ EOTEMPLATE
1543
1601
  ##
1544
1602
  def list_date(dates,section,times=nil,output=nil,opt={})
1545
1603
  opt[:totals] ||= false
1604
+ opt[:sort_tags] ||= false
1546
1605
  section = guess_section(section)
1547
1606
  # :date_filter expects an array with start and end date
1548
1607
  if dates.class == String
1549
1608
  dates = [dates, dates]
1550
1609
  end
1551
1610
 
1552
- list_section({:section => section, :count => 0, :order => "asc", :date_filter => dates, :times => times, :output => output, :totals => opt[:totals] })
1611
+ list_section({:section => section, :count => 0, :order => "asc", :date_filter => dates, :times => times, :output => output, :totals => opt[:totals], :sort_tags => opt[:sort_tags] })
1553
1612
  end
1554
1613
 
1555
1614
  ##
@@ -1562,8 +1621,9 @@ EOTEMPLATE
1562
1621
  ##
1563
1622
  def yesterday(section,times=nil,output=nil,opt={})
1564
1623
  opt[:totals] ||= false
1624
+ opt[:sort_tags] ||= false
1565
1625
  section = guess_section(section)
1566
- list_section({:section => section, :count => 0, :order => "asc", :yesterday => true, :times => times, :output => output, :totals => opt[:totals] })
1626
+ list_section({:section => section, :count => 0, :order => "asc", :yesterday => true, :times => times, :output => output, :totals => opt[:totals], :sort_tags => opt[:sort_tags] })
1567
1627
  end
1568
1628
 
1569
1629
  ##
@@ -1576,10 +1636,12 @@ EOTEMPLATE
1576
1636
  def recent(count=10,section=nil,opt={})
1577
1637
  times = opt[:t] || true
1578
1638
  opt[:totals] ||= false
1639
+ opt[:sort_tags] ||= false
1640
+
1579
1641
  cfg = @config['templates']['recent']
1580
1642
  section ||= @current_section
1581
1643
  section = guess_section(section)
1582
- list_section({:section => section, :wrap_width => cfg['wrap_width'], :count => count, :format => cfg['date_format'], :template => cfg['template'], :order => "asc", :times => times, :totals => opt[:totals] })
1644
+ list_section({:section => section, :wrap_width => cfg['wrap_width'], :count => count, :format => cfg['date_format'], :template => cfg['template'], :order => "asc", :times => times, :totals => opt[:totals], :sort_tags => opt[:sort_tags] })
1583
1645
  end
1584
1646
 
1585
1647
  ##
@@ -1601,7 +1663,6 @@ EOTEMPLATE
1601
1663
  ## @param format (String) return format (html, json, or text)
1602
1664
  ##
1603
1665
  def tag_times(format="text", sort_by_name = false)
1604
-
1605
1666
  return "" if @timers.empty?
1606
1667
 
1607
1668
  max = @timers.keys.sort_by {|k| k.length }.reverse[0].length + 1
@@ -1711,11 +1772,15 @@ EOS
1711
1772
  regex = Regexp.new('@' + rx + '\b')
1712
1773
 
1713
1774
  matches = text.scan(regex)
1714
-
1715
1775
  matches.each {|m|
1716
- puts rx,r
1717
- new_tag = m[0].sub(Regexp.new(rx), r)
1718
- puts new_tag
1776
+ new_tag = r
1777
+ if m.kind_of?(Array)
1778
+ index = 1
1779
+ m.each {|v|
1780
+ new_tag = new_tag.gsub('\\' + index.to_s, v)
1781
+ index = index + 1
1782
+ }
1783
+ end
1719
1784
  tail_tags.push(new_tag)
1720
1785
  } if matches
1721
1786
  end
@@ -1789,6 +1854,10 @@ EOS
1789
1854
  if seconds.nil?
1790
1855
  return [0, 0, 0]
1791
1856
  end
1857
+ if seconds =~ /(\d+):(\d+):(\d+)/
1858
+ h, m, s = [$1, $2, $3]
1859
+ seconds = (h.to_i * 60 * 60) + (m.to_i * 60) + s.to_i
1860
+ end
1792
1861
  minutes = (seconds / 60).to_i
1793
1862
  hours = (minutes / 60).to_i
1794
1863
  days = (hours / 24).to_i
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.38
4
+ version: 1.0.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-21 00:00:00.000000000 Z
11
+ date: 2021-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake