doing 1.0.39 → 1.0.44

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62aab464d54aaaa9afbe992bc0e7d466d79ee24b9bdc5127ae8b45cfb4895795
4
- data.tar.gz: '048bc4ec14d0df9c0c44940b9bd0cfc25c8167ea78db3e64526f8fdbad119588'
3
+ metadata.gz: bbe619696336e23ee543e4519f139c62ecccbd025d58b9ca69be1b8256805c82
4
+ data.tar.gz: af9210306d1a2d868ecdc6208b6d1cbc508c22be67072e13d470892de80c29cf
5
5
  SHA512:
6
- metadata.gz: 5500256aa08f6a75a83118a6c4521453f1900a67d69bc57d31a753c4f064c5d9597675152508f5770eb2fbe036b11c7bbe506376cc1da48c6b9919169cb2c849
7
- data.tar.gz: 51607b30fd337af37e21bea90d5b5e91c3fdf6d15c4909fce3f35836337d5f791504644afb5d9505e376bbd53e7b5e0ae386da2695d877bb3fac455c3cf9778b
6
+ metadata.gz: 546e4f4a5c9022656461dbe6399142ad326801c88f22d162f620f4f5eadb477f74a09c45367930583ccd02378a06a7076e334c7cb199c0f42e1fdb7050bf9f5c
7
+ data.tar.gz: f6f8c75163349dec7a2ab0d4919ebf201f68d6acb0de3ea7698e6bb1a7a0ae3f483c2e3fbeb5ac88b69e53141ac15a73cd68e5a6131c310046df8a7300ed588c
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.39'
2
+ VERSION = '1.0.44'
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
@@ -1716,7 +1777,7 @@ EOS
1716
1777
  if m.kind_of?(Array)
1717
1778
  index = 1
1718
1779
  m.each {|v|
1719
- new_tag = new_tag.sub('\\' + index.to_s, v)
1780
+ new_tag = new_tag.gsub('\\' + index.to_s, v)
1720
1781
  index = index + 1
1721
1782
  }
1722
1783
  end
@@ -1793,6 +1854,10 @@ EOS
1793
1854
  if seconds.nil?
1794
1855
  return [0, 0, 0]
1795
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
1796
1861
  minutes = (seconds / 60).to_i
1797
1862
  hours = (minutes / 60).to_i
1798
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.39
4
+ version: 1.0.44
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