punched 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/punched +34 -9
- data/lib/punchcard.rb +19 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fdd61f9eabb988d556bbd57326f7e3183ab0e06bc89ad0793b7b6b10297d674
|
4
|
+
data.tar.gz: 0b01c0843ef8b1fdb35db945499abe6471eb02ddd9cd235d3a2573b1c62397ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab670118039f178ccd2d2c86d73dbbffbeefd5143db78f8f8b4ac96fa978e07c41860260fd8501af17140786cd9816ce595b60c3348b20eb16d7e8584adef6c5
|
7
|
+
data.tar.gz: 882f24d878d733bc45bb38e94553968fad541e36a2eb08a29c5278d05f57de473e9ae3afcb312771b8594eeabf711d82e762ac991307c442e953e937a2471af2
|
data/bin/punched
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
THIS_FILE = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
5
|
+
|
6
|
+
begin
|
7
|
+
require File.expand_path(File.dirname(THIS_FILE) + '/../lib/punchcard')
|
8
|
+
rescue LoadError
|
9
|
+
require 'punchcard'
|
10
|
+
end
|
3
11
|
|
4
|
-
require 'punchcard.rb'
|
5
12
|
require 'csv'
|
6
13
|
require 'markdown-tables'
|
7
14
|
require 'date'
|
@@ -14,7 +21,13 @@ class UnknownActionError < StandardError; end
|
|
14
21
|
#
|
15
22
|
|
16
23
|
def available_actions
|
17
|
-
PunchCard.new(nil).public_methods(false).reject { |item|
|
24
|
+
PunchCard.new(nil).public_methods(false).reject { |item|
|
25
|
+
item.to_s.end_with?('=') || item.to_s == 'project'
|
26
|
+
}.concat(global_available_actions).sort
|
27
|
+
end
|
28
|
+
|
29
|
+
def global_available_actions
|
30
|
+
[:all, :totalsum]
|
18
31
|
end
|
19
32
|
|
20
33
|
def action_available?(action)
|
@@ -37,11 +50,11 @@ def all(action)
|
|
37
50
|
end
|
38
51
|
|
39
52
|
labels = ['project', 'status', 'last active on', 'total duration', 'hourly rate', 'earnings']
|
40
|
-
data =
|
41
|
-
|
42
|
-
last_activity = !
|
43
|
-
|
44
|
-
|
53
|
+
data = call_punchcards_by_pattern('*', 'csv').map do |csv_string|
|
54
|
+
csv_data = CSV.parse(csv_string)[0]
|
55
|
+
last_activity = !csv_data[2].empty? ? DateTime.parse(csv_data[2]).to_time.to_i : 0
|
56
|
+
csv_data.push(last_activity)
|
57
|
+
csv_data
|
45
58
|
end.sort_by(&:last).reverse.map do |row|
|
46
59
|
row[0...-1]
|
47
60
|
end
|
@@ -81,6 +94,13 @@ def call_punchcard(selected_action, project_name)
|
|
81
94
|
end
|
82
95
|
end
|
83
96
|
|
97
|
+
def call_punchcards_by_pattern(pattern, action)
|
98
|
+
Dir["#{PunchCard::SETTINGS_DIR}/#{pattern}"].map do |file|
|
99
|
+
project_name = File.basename(file)
|
100
|
+
call_punchcard(action, project_name)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
84
104
|
if ['-h', '--help', 'help'].include?(ARGV.first)
|
85
105
|
puts(usage)
|
86
106
|
exit
|
@@ -93,6 +113,11 @@ if selected_action
|
|
93
113
|
begin
|
94
114
|
if selected_action == 'all'
|
95
115
|
all(ARGV[1] || 'plain')
|
116
|
+
elsif selected_action == 'totalsum'
|
117
|
+
pattern = ARGV[1] || '*'
|
118
|
+
puts PunchCard.humanize_duration(
|
119
|
+
call_punchcards_by_pattern(pattern, 'total').reduce(&:+)
|
120
|
+
)
|
96
121
|
else
|
97
122
|
result = call_punchcard(selected_action, project_name)
|
98
123
|
if result.is_a?(Hash)
|
@@ -104,6 +129,6 @@ if selected_action
|
|
104
129
|
rescue PunchCardError => e
|
105
130
|
exit_with_error! "Error: #{e.message}"
|
106
131
|
rescue UnknownActionError => e
|
107
|
-
exit_with_error! "Unrecognized action '#{selected_action ||
|
132
|
+
exit_with_error! "Unrecognized action '#{selected_action || e.message}'\n#{usage}"
|
108
133
|
end
|
109
134
|
end
|
data/lib/punchcard.rb
CHANGED
@@ -11,7 +11,7 @@ class PunchCard
|
|
11
11
|
HOURLY_RATE_PATTERN = /^\s*(\d+)([^\d]+)*\s*/i.freeze
|
12
12
|
TIME_POINT_PATTERN = /^((\d+|.+?\s[\+\-]\d{4}?\s*)(\-)*(\d+|\s.+\d?)*)$/.freeze
|
13
13
|
META_KEY_PATTERN = /^([a-zA-Z0-9]+)\:\s*(.*)$/.freeze
|
14
|
-
VERSION = '1.1.
|
14
|
+
VERSION = '1.1.1'.freeze
|
15
15
|
|
16
16
|
attr_accessor :project
|
17
17
|
|
@@ -167,6 +167,21 @@ class PunchCard
|
|
167
167
|
datetime.strftime('%F %T')
|
168
168
|
end
|
169
169
|
|
170
|
+
def self.humanize_duration(duration)
|
171
|
+
hours = duration / (60 * 60)
|
172
|
+
minutes = (duration / 60) % 60
|
173
|
+
seconds = duration % 60
|
174
|
+
"#{decimal_digits(hours)}:#{decimal_digits(minutes)}:#{decimal_digits(seconds)}"
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.decimal_digits(digit)
|
178
|
+
if digit.to_i < 10
|
179
|
+
"0#{digit}"
|
180
|
+
else
|
181
|
+
digit.to_s
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
170
185
|
private
|
171
186
|
|
172
187
|
def hourly_rate
|
@@ -192,29 +207,14 @@ class PunchCard
|
|
192
207
|
end
|
193
208
|
|
194
209
|
def humanized_total
|
195
|
-
humanize_duration total
|
210
|
+
self.class.humanize_duration total
|
196
211
|
end
|
197
212
|
|
198
213
|
def duration(starttime, endtime)
|
199
214
|
if starttime
|
200
|
-
humanize_duration endtime - starttime
|
215
|
+
self.class.humanize_duration endtime - starttime
|
201
216
|
else
|
202
|
-
humanize_duration 0
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
def humanize_duration(duration)
|
207
|
-
hours = duration / (60 * 60)
|
208
|
-
minutes = (duration / 60) % 60
|
209
|
-
seconds = duration % 60
|
210
|
-
"#{decimal_digits(hours)}:#{decimal_digits(minutes)}:#{decimal_digits(seconds)}"
|
211
|
-
end
|
212
|
-
|
213
|
-
def decimal_digits(digit)
|
214
|
-
if digit.to_i < 10
|
215
|
-
"0#{digit}"
|
216
|
-
else
|
217
|
-
digit.to_s
|
217
|
+
self.class.humanize_duration 0
|
218
218
|
end
|
219
219
|
end
|
220
220
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: punched
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Philipp Staender
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-02-
|
11
|
+
date: 2019-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: markdown-tables
|