twstats 0.1.4 → 0.2

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
- SHA1:
3
- metadata.gz: c03859f83739b7704e23e9df4faba575ea6f3aa6
4
- data.tar.gz: 5906375e59625f9a5ffef39dbd8905325e2ea4f4
2
+ SHA256:
3
+ metadata.gz: b03a403d2eac6f0356f6e8bad78c073c93565139101566472b67d1a2901c0368
4
+ data.tar.gz: 44e5e4ae4cd5eff7e937882fdf01dcddb12d3130a2427ee0ea08cee0a3ed8a1e
5
5
  SHA512:
6
- metadata.gz: 3a6d20cc0fe85c57ad9872e33f16237d54440725cbed8e6cc17dc155a090e96cdf970b2a56dab224e5fc403275872bb470e34128a39747ad7b3a622f3e6667ef
7
- data.tar.gz: 7d25b85fb90cfc3da98763eca74f47c4f3d6377fab7075e2faf3be86912e7000c6ce585797bc5155ef9e73f555e5ee0196f198de94de18ae4b619ec4f63ee287
6
+ metadata.gz: f97828091ec24a7edc400dbf79a82ff4861ea9b17ee4cc937c2709c1fde0c1fae919534c1b89f39efcf22e31062dc37ea0c306e1e9f3f82dac1ef6854af7acff
7
+ data.tar.gz: f7aac1d4b1569fe79b5218601f59305f2b73409281f1cdeafd7eaa06c89b9ed28200d5913d915b779800cbd9aa537110509db078a41011fb72593af128ae2eff
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /vendor/
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- twstats (0)
4
+ twstats (0.1.4)
5
+ rainbow (~> 3.0)
5
6
  tty-prompt (~> 0.17)
6
7
 
7
8
  GEM
@@ -14,6 +15,7 @@ GEM
14
15
  pastel (0.7.2)
15
16
  equatable (~> 0.5.0)
16
17
  tty-color (~> 0.4.0)
18
+ rainbow (3.0.0)
17
19
  rake (10.5.0)
18
20
  rspec (3.8.0)
19
21
  rspec-core (~> 3.8.0)
@@ -13,9 +13,8 @@ module Twstats
13
13
  {name: 'Projects', value: 0},
14
14
  {name: 'People', value: 1},
15
15
  {name: 'Tags', value: 2},
16
- {name: 'Billable vs non-villable', value: 3},
17
- {name: 'Full stats', value: 4},
18
- {name: 'Back', value: 5}
16
+ {name: 'Full stats', value: 3},
17
+ {name: 'Back', value: 4}
19
18
  ]
20
19
  MENU_CHOICES = [
21
20
  {name: 'Stats', value: 0},
@@ -29,19 +29,45 @@ module Twstats
29
29
  @logs << log
30
30
  end
31
31
 
32
- def get_total_time(object, element)
32
+ def mean_time
33
+ logs.inject(0) {|sum, log| sum + log.decimal_time }.to_f/logs.size
34
+ end
35
+
36
+ def mean_time_per_task
37
+ time_per_task = []
38
+ tasks.each do |task|
39
+ time_per_task << logs.select{|ll| ll.task == task}.inject(0){|sum, ll| sum + ll.decimal_time}
40
+ end
41
+ time_per_task.inject(0){|sum, x| sum + x}/time_per_task.size
42
+ end
43
+
44
+ def get_total_time(object, element, filter_billable)
45
+ billable = 0
46
+ non_billable = 0
33
47
  case object
34
48
  when :projects
35
- logs.select{|log| log.project == element}.inject(0){ |sum, l| sum + l.decimal_time}
49
+ billable = logs.select{|log| log.project == element && log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
50
+ non_billable = logs.select{|log| log.project == element && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
36
51
  when :tags
37
- logs.select{|log| log.tags.include?(element)}.inject(0){ |sum, l| sum + l.decimal_time}
52
+ billable = logs.select{|log| log.tags.include?(element) && log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
53
+ non_billable = logs.select{|log| log.tags.include?(element) && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
38
54
  when :people
39
- logs.select{|log| log.who == element}.inject(0){ |sum, l| sum + l.decimal_time}
55
+ billable = logs.select{|log| log.who == element && log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
56
+ non_billable = logs.select{|log| log.who == element && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
40
57
  when :tasks
41
- logs.select{|log| log.task == element}.inject(0){ |sum, l| sum + l.decimal_time}
58
+ billable = logs.select{|log| log.task == element && log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
59
+ non_billable = logs.select{|log| log.task == element && !log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
60
+ when :all
61
+ billable = logs.select{|log| log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
62
+ non_billable = logs.select{|log| !log.billable}.inject(0){ |sum, l| sum + l.decimal_time}
42
63
  else
43
- -99999
64
+ return -99999
65
+ end
66
+ if filter_billable
67
+ return billable, non_billable
68
+ else
69
+ return billable + non_billable
44
70
  end
45
71
  end
46
72
  end
47
- end
73
+ end
@@ -1,20 +1,22 @@
1
1
  require 'tty-prompt'
2
+ require 'rainbow/refinement'
3
+ using Rainbow
2
4
 
3
5
  require_relative 'csv_reader'
4
6
 
5
7
  module Twstats
6
8
  class Runner
7
- def initialize
9
+ def initialize(file = nil)
8
10
  # Load interactive console
9
11
  @prompt = TTY::Prompt.new
10
- puts WELLCOME_MESSAGE
12
+ puts WELLCOME_MESSAGE.bright
11
13
  # Ask for the csv file
12
- file = @prompt.ask('Specify the CSV file from a Teamwork time log export', default: 'exportTimeLog.csv') do |input|
14
+ file ||= @prompt.ask('Specify the CSV file from a Teamwork time log export', default: 'exportTimeLog.csv') do |input|
13
15
  input.modify :chomp
14
16
  end
15
17
  @csv = CSVReader.new(file)
16
18
  loop do
17
- option = @prompt.select("Choose an option", Twstats::MENU_CHOICES)
19
+ option = @prompt.select("Choose an option", Twstats::MENU_CHOICES, cycle: true)
18
20
  case option
19
21
  when 0
20
22
  show_stats_menu
@@ -30,7 +32,7 @@ module Twstats
30
32
 
31
33
  def show_stats_menu
32
34
  loop do
33
- option = @prompt.select("Select what time logging stats you want to see", Twstats::STATS_MENU_CHOICES)
35
+ option = @prompt.select("Select what time logging stats you want to see", Twstats::STATS_MENU_CHOICES, cycle: true)
34
36
  case option
35
37
  when 0
36
38
  show_stats :projects
@@ -39,10 +41,8 @@ module Twstats
39
41
  when 2
40
42
  show_stats :tags
41
43
  when 3
42
- show_bil_vs_non_stats
43
- when 4
44
44
  show_full_stats
45
- when 5
45
+ when 4
46
46
  return
47
47
  else
48
48
  puts 'Option not recognized'
@@ -50,16 +50,22 @@ module Twstats
50
50
  end
51
51
  end
52
52
 
53
- def show_stats(obj)
54
- puts "Time logged vs #{obj.to_s}:"
53
+ def show_stats(obj, filter_billable = nil)
54
+ puts "Time logged vs #{obj.to_s}:" if filter_billable.nil?
55
55
  toshow = {}
56
56
  max = 0
57
+ filter_billable ||= @prompt.yes?('Do you want to filter billable and non-billable time?', default: true)
57
58
  @csv.send(obj).each do |element|
58
- toshow[element] = @csv.get_total_time(obj, element).round(2)
59
+ toshow[element] = @csv.get_total_time(obj, element, filter_billable)
59
60
  max = element.size if max < element.size
60
61
  end
61
62
  toshow.sort_by{ |k,v| v}.reverse.to_h.each do |k,v|
62
- puts " - #{k.ljust(max,' ')} -> #{v}"
63
+ if filter_billable
64
+ puts " - #{k.ljust(max,' ').bright.blue} | #{"Billable:".ljust(13," ").bright} #{v[0].round(2)} (#{((v[0]/(v[0]+v[1]))*100).round(2)} %)" unless v[0].zero?
65
+ puts " #{"".ljust(max,' ').bright.blue} | #{"Non-billable:".bright} #{v[1].round(2)}" unless v[1].zero?
66
+ else
67
+ puts " - #{k.ljust(max,' ').bright.blue} | #{v.round(2)}" unless v.zero?
68
+ end
63
69
  end
64
70
  end
65
71
 
@@ -67,5 +73,36 @@ module Twstats
67
73
 
68
74
  end
69
75
 
76
+ def show_full_stats
77
+ billable, non_billable = @csv.get_total_time(:all, nil, true)
78
+ to_bill = @prompt.yes? 'Do you want to calculate the billed amount?'
79
+ if to_bill
80
+ amount_per_hour = @prompt.ask 'What the amount billed per hour?', default: 46
81
+ end
82
+ section "Total time spent"
83
+ puts " - Billable ".bright.blue + " | " + billable.round(2).to_s
84
+ puts " - Non-billable ".bright.blue + " | " + non_billable.round(2).to_s
85
+ if to_bill
86
+ puts " - Billed amount ".bright.blue + " | " + (billable*amount_per_hour).round(2).to_s + " € "
87
+ end
88
+ section "People involved"
89
+ show_stats :people, true
90
+ section "Tags used"
91
+ show_stats :tags, true
92
+ section "Usefull metrics"
93
+ show_metrics
94
+ end
95
+
96
+ def section(text)
97
+ puts ""
98
+ puts (" "+text+" ").center(70,"*").bright
99
+ end
100
+
101
+ def show_metrics
102
+ mean = @csv.logs.inject(0) {|sum, log| sum + log.decimal_time }.to_f/@csv.logs.size
103
+ mean_per_task = @csv.mean_time_per_task
104
+ puts " - Mean time logged: ".bright.blue + mean.round(2).to_s
105
+ puts " - Mean time per task: ".bright.blue + mean_per_task.round(2).to_s
106
+ end
70
107
  end
71
- end
108
+ end
@@ -8,6 +8,7 @@ module Twstats
8
8
  attr_reader :tags
9
9
  attr_reader :project
10
10
  attr_reader :task
11
+ attr_reader :billable
11
12
 
12
13
 
13
14
  # Class use to store the information needed form a given log
@@ -20,7 +21,7 @@ module Twstats
20
21
  @tags = row["Tags"].split(',')
21
22
  @project = row["Project"]
22
23
  @task = row["Task"]
23
- @billable = row["Is it Billable?"]
24
+ @billable = !row["Is it Billable?"].to_i.zero?
24
25
  end
25
26
  end
26
- end
27
+ end
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency "rake", "~> 10.0"
37
37
  spec.add_development_dependency "rspec", "~> 3.0"
38
38
  spec.add_runtime_dependency "tty-prompt", "~> 0.17"
39
+ spec.add_runtime_dependency "rainbow", "~> 3.0"
39
40
 
40
- spec.required_ruby_version = '~> 2.0'
41
+ spec.required_ruby_version = '~> 2.1'
41
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twstats
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - J.P. Araque
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.17'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rainbow
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
69
83
  description: Teamwork allows to log time for all tasks within a project but the stats
70
84
  capabilities do not allow for a quick overview of time loggin stats. TWStats produces
71
85
  useful stats from a CSV file exported from Teamwork
@@ -107,7 +121,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '2.0'
124
+ version: '2.1'
111
125
  required_rubygems_version: !ruby/object:Gem::Requirement
112
126
  requirements:
113
127
  - - ">="
@@ -115,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
129
  version: '0'
116
130
  requirements: []
117
131
  rubyforge_project:
118
- rubygems_version: 2.6.11
132
+ rubygems_version: 2.7.7
119
133
  signing_key:
120
134
  specification_version: 4
121
135
  summary: Read a csv file generate by Teamwork to quickly get some stats from time