twstats 0.2.2 → 0.2.3
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/twstats.rb +2 -2
- data/lib/twstats/csv_reader.rb +15 -1
- data/lib/twstats/extensions.rb +16 -0
- data/lib/twstats/runner.rb +50 -4
- data/lib/twstats/tw_log.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27db2b5244ab293d6e6f955c7392b1473daeaf2832c0a5f9db342a10216a72df
|
4
|
+
data.tar.gz: 1a475fe0708379be56cfd4cf9329c84cf03b4c7b21a4572a4c1a45c8c6e39608
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09a95242b4c137c7cdc474be974ab3b1f9623daeb5caaf2af63a411a0556914d30ca77a1b18f687dafd99e848e85f25b2e7486afe88a9c7399e7f1671c7c32cf'
|
7
|
+
data.tar.gz: 0470c445f623518a781d4da31376c3161e1ead38f3df8b32aa7a60c3fa98507edcae85c2d5c986d7758e23b8196a4554dfe332e703db6b80d27da52b9eb439a9
|
data/Gemfile.lock
CHANGED
data/lib/twstats.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
require_relative 'twstats/extensions'
|
1
2
|
require_relative 'twstats/version'
|
3
|
+
require_relative 'twstats/tw_log'
|
2
4
|
require_relative 'twstats/csv_reader'
|
3
5
|
require_relative 'twstats/runner'
|
4
|
-
require_relative 'twstats/tw_log'
|
5
6
|
|
6
7
|
module Twstats
|
7
|
-
|
8
8
|
DEFAULT_OPTIONS = {encoding: 'ISO-8859-1:UTF-8', headers: true}
|
9
9
|
WELLCOME_MESSAGE = "\n***************************************************************************************
|
10
10
|
** TWStats helps you to get some stats from a CSV export of Time loggin gin Teamwork **
|
data/lib/twstats/csv_reader.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'csv'
|
2
|
-
require "twstats/tw_log"
|
3
2
|
|
4
3
|
module Twstats
|
5
4
|
class CSVReader
|
@@ -74,5 +73,20 @@ module Twstats
|
|
74
73
|
sorted_logs = logs.map{|l| l.date}.sort
|
75
74
|
(sorted_logs[-1] - sorted_logs[0]).to_i <= 7
|
76
75
|
end
|
76
|
+
|
77
|
+
def not_tagged_tasks
|
78
|
+
total_time = 0
|
79
|
+
list = []
|
80
|
+
logs.each do |log|
|
81
|
+
if log.tags.empty?
|
82
|
+
list << log
|
83
|
+
total_time += log.decimal_time
|
84
|
+
end
|
85
|
+
end
|
86
|
+
{
|
87
|
+
total_time: total_time,
|
88
|
+
list: list
|
89
|
+
}
|
90
|
+
end
|
77
91
|
end
|
78
92
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Extend the string core class to add the truncate method from Rails
|
2
|
+
class String
|
3
|
+
def truncate(truncate_at, options = {})
|
4
|
+
return dup unless length > truncate_at
|
5
|
+
|
6
|
+
options[:omission] ||= '...'
|
7
|
+
length_with_room_for_omission = truncate_at - options[:omission].length
|
8
|
+
stop = if options[:separator]
|
9
|
+
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
|
10
|
+
else
|
11
|
+
length_with_room_for_omission
|
12
|
+
end
|
13
|
+
|
14
|
+
"#{self[0...stop]}#{options[:omission]}"
|
15
|
+
end
|
16
|
+
end
|
data/lib/twstats/runner.rb
CHANGED
@@ -65,10 +65,38 @@ module Twstats
|
|
65
65
|
puts " - #{k.ljust(max,' ').bright.blue} | #{v.round(2)}" unless v.zero?
|
66
66
|
end
|
67
67
|
end
|
68
|
+
show_not_tagged_section false
|
68
69
|
end
|
69
70
|
|
70
|
-
def
|
71
|
+
def ranking_from_not_tagged(list)
|
72
|
+
result = {}
|
73
|
+
list[:list].each do |log|
|
74
|
+
result[log.who] ||= 0
|
75
|
+
result[log.who] += log.decimal_time
|
76
|
+
end
|
77
|
+
result.sort_by{|k,v| v}.reverse.to_h
|
78
|
+
end
|
79
|
+
|
80
|
+
def print_table(log_list)
|
81
|
+
167.times{print '-'}
|
82
|
+
puts "\n|"+'Date'.center(12,' ').bright+'|'+'Time'.center(6,' ').bright+'|'+'Who'.center(20, ' ').bright+
|
83
|
+
'|'+'Description'.center(78,' ').bright+'|'+'Tags'.center(24,' ').bright+'|'+'Task'.center(20, ' ').bright+'|'
|
84
|
+
167.times{print '-'}
|
85
|
+
puts ""
|
86
|
+
log_list.each do |log|
|
87
|
+
puts table_line(log)
|
88
|
+
end
|
89
|
+
167.times{print '-'}
|
90
|
+
puts ""
|
91
|
+
end
|
71
92
|
|
93
|
+
def table_line(log)
|
94
|
+
"|"+"#{log.date.strftime('%d/%m/%Y')}".truncate(10).center(12,' ')+
|
95
|
+
'|'+"#{log.decimal_time.round(2)}".truncate(4).center(6,' ')+
|
96
|
+
'|'+"#{log.who}".truncate(18).center(20, ' ')+
|
97
|
+
'|'+"#{log.description}".truncate(76).ljust(78,' ')+
|
98
|
+
'|'+"#{log.tags.join(', ')}".truncate(22).center(24,' ')+
|
99
|
+
'|'+"#{log.task}".truncate(18).center(20, ' ')+'|'
|
72
100
|
end
|
73
101
|
|
74
102
|
def show_full_stats
|
@@ -87,10 +115,28 @@ module Twstats
|
|
87
115
|
show_stats :people, true
|
88
116
|
section "Tags used"
|
89
117
|
show_stats :tags, true
|
118
|
+
show_not_tagged_section(true)
|
90
119
|
section "Usefull metrics"
|
91
120
|
show_metrics
|
92
121
|
end
|
93
122
|
|
123
|
+
def show_not_tagged_section(table)
|
124
|
+
not_tagged = @csv.not_tagged_tasks
|
125
|
+
unless not_tagged[:list].empty?
|
126
|
+
section("Tasks not tagged in this report")
|
127
|
+
puts "A total of #{not_tagged[:list].size} logs have not been tagged:"
|
128
|
+
puts " - A total time of #{not_tagged[:total_time]} is not tagged properly."
|
129
|
+
puts " - Impact by employee: "
|
130
|
+
ranking_from_not_tagged(not_tagged).each do |user, time|
|
131
|
+
puts "\t - #{user.ljust(30,' ').bright.blue} | #{time}"
|
132
|
+
end
|
133
|
+
table = @prompt.yes?('Do you want to see what tasks have not been tagged?', default: true) if table.nil?
|
134
|
+
if table
|
135
|
+
print_table not_tagged[:list]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
94
140
|
def section(text)
|
95
141
|
puts ""
|
96
142
|
puts (" "+text+" ").center(70,"*").bright
|
@@ -115,9 +161,9 @@ module Twstats
|
|
115
161
|
@csv.people.each do |person|
|
116
162
|
billable, non_billable = @csv.get_total_time(:people, person, true)
|
117
163
|
info[person] = {rate: billable * 100 / hours,
|
118
|
-
|
119
|
-
|
120
|
-
|
164
|
+
not_billed: hours - billable - non_billable,
|
165
|
+
billable: billable,
|
166
|
+
non_billable: non_billable
|
121
167
|
}
|
122
168
|
end
|
123
169
|
info.sort_by{|x,v| v[:rate] }.reverse.each do |person, data|
|
data/lib/twstats/tw_log.rb
CHANGED
@@ -19,7 +19,7 @@ module Twstats
|
|
19
19
|
@decimal_time = row["Decimal Hours"].to_f
|
20
20
|
@time = (DateTime.parse(row["End Date/Time"]) - DateTime.parse(row["Date/Time"]))*24
|
21
21
|
@description = row["Description"]
|
22
|
-
@tags = row["Tags"].split(',')
|
22
|
+
@tags = row['Tags'].nil? ? [] : row["Tags"].split(',')
|
23
23
|
@project = row["Project"]
|
24
24
|
@task = row["Task"]
|
25
25
|
@billable = !row["Is it Billable?"].to_i.zero?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twstats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- J.P. Araque
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -104,6 +104,7 @@ files:
|
|
104
104
|
- exe/twstats
|
105
105
|
- lib/twstats.rb
|
106
106
|
- lib/twstats/csv_reader.rb
|
107
|
+
- lib/twstats/extensions.rb
|
107
108
|
- lib/twstats/runner.rb
|
108
109
|
- lib/twstats/tw_log.rb
|
109
110
|
- lib/twstats/version.rb
|