gpuzzletime 0.1.0 → 0.2.0
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/.overcommit.yml +26 -0
- data/.rubocop.yml +8 -0
- data/README.md +19 -0
- data/gpuzzletime.gemspec +16 -14
- data/lib/gpuzzletime/app.rb +42 -34
- data/lib/gpuzzletime/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '085c039e47e90785456469afa634a2bdec1a0827f6338002ad328aec65bd3ebe'
|
4
|
+
data.tar.gz: 90c4d988689fbdd1984b8d03ada7cb7c323239275dcb58bdf93966d7d17e7b0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ca42c92cb96a54088514f351317a09c96bfc8d566fa12153f7a2ee843900575bca8389913223cd1ebd8ab8b37aeb0f5f9ae549c8545be4e0e5b080bc2551011
|
7
|
+
data.tar.gz: cb59f1b6ef96d3b94eab51713d39ff8f3fa18980d45815988804da871fac27210470d83bd7c8641f6ee59eefbcf771dfc494dcef8e2031168eaf2f038cfc4b3e
|
data/.overcommit.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Use this file to configure the Overcommit hooks you wish to use. This will
|
2
|
+
# extend the default configuration defined in:
|
3
|
+
# https://github.com/brigade/overcommit/blob/master/config/default.yml
|
4
|
+
#
|
5
|
+
# For a complete list of hooks, see:
|
6
|
+
# https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook
|
7
|
+
#
|
8
|
+
# For a complete list of options that you can use to customize hooks, see:
|
9
|
+
# https://github.com/brigade/overcommit#configuration
|
10
|
+
|
11
|
+
PreCommit:
|
12
|
+
RuboCop:
|
13
|
+
enabled: true
|
14
|
+
on_warn: fail # Treat all warnings as failures
|
15
|
+
|
16
|
+
TrailingWhitespace:
|
17
|
+
enabled: true
|
18
|
+
# exclude:
|
19
|
+
# - '**/db/structure.sql' # Ignore trailing whitespace in generated files
|
20
|
+
|
21
|
+
#PostCheckout:
|
22
|
+
# ALL: # Special hook name that customizes all hooks of this type
|
23
|
+
# quiet: true # Change all post-checkout hooks to only display output on failure
|
24
|
+
#
|
25
|
+
# IndexTags:
|
26
|
+
# enabled: true # Generate a tags file with `ctags` each time HEAD changes
|
data/.rubocop.yml
ADDED
data/README.md
CHANGED
@@ -27,6 +27,15 @@ small tooling to transfer timelog-entries from gtimelog's timelog.txt to the Puz
|
|
27
27
|
- [ ] start/end time as indicator?
|
28
28
|
- [ ] offer rounding times to the next 5, 10 or 15 minutes
|
29
29
|
- [ ] allow to add entries from the command-line
|
30
|
+
- [ ] handle time-account and billable better
|
31
|
+
- [ ] import time-accounts from ptime (https://time.puzzle.ch/work_items/search.json?q=search%20terms)
|
32
|
+
- [ ] with a dedicated cli?
|
33
|
+
- [ ] from a REST-Endpoint of PTime?
|
34
|
+
- [ ] automatically prefill billable
|
35
|
+
- [ ] from time-accounts
|
36
|
+
- [ ] from *-notation
|
37
|
+
- [ ] allow to have a list of "favourite" time-accounts
|
38
|
+
- [ ] select best-matching time-account according to tags, possibly limited to the favourites
|
30
39
|
|
31
40
|
|
32
41
|
## Installation
|
@@ -45,6 +54,7 @@ Currently supported actions are
|
|
45
54
|
|
46
55
|
- show
|
47
56
|
- upload
|
57
|
+
- edit
|
48
58
|
|
49
59
|
### Date-Identifier
|
50
60
|
|
@@ -54,9 +64,18 @@ For reusability in a shell-history the following keywords are supported:
|
|
54
64
|
|
55
65
|
- today
|
56
66
|
- yesterday
|
67
|
+
- last
|
57
68
|
|
58
69
|
If nothing is specified, the action is applied to all entries.
|
59
70
|
|
71
|
+
### Edit-Identifier
|
72
|
+
|
73
|
+
When the action is "edit", the next argument is treated as script that shoudl be edited.
|
74
|
+
|
75
|
+
If nothing is passed, the main timelog.txt is loaded.
|
76
|
+
|
77
|
+
Otherwise, a script to determine the time-account is loaded.
|
78
|
+
|
60
79
|
## Development
|
61
80
|
|
62
81
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec gpuzzletime` to use the gem in this directory, ignoring other installed copies of this gem.
|
data/gpuzzletime.gemspec
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'gpuzzletime/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'gpuzzletime'
|
8
9
|
spec.version = Gpuzzletime::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Matthias Viehweger']
|
11
|
+
spec.email = ['kronn@kronn.de']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
+
spec.summary = 'Move time-entries from gTimelog to PuzzleTime'
|
13
14
|
# spec.description = %q{}
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
15
|
+
spec.homepage = 'https://github.com/kronn/gpuzzletime'
|
16
|
+
spec.license = 'MIT'
|
16
17
|
|
17
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
-
spec.bindir =
|
19
|
+
spec.bindir = 'exe'
|
19
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ['lib']
|
21
22
|
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
24
|
+
spec.add_development_dependency 'overcommit', '~> 0.45'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
spec.add_development_dependency 'rubocop', '~> 0.50'
|
26
28
|
end
|
data/lib/gpuzzletime/app.rb
CHANGED
@@ -4,8 +4,8 @@ require 'date'
|
|
4
4
|
require 'erb'
|
5
5
|
require 'pathname'
|
6
6
|
|
7
|
-
# Wrapper for everything
|
8
7
|
module Gpuzzletime
|
8
|
+
# Wrapper for everything
|
9
9
|
class App
|
10
10
|
def initialize(args)
|
11
11
|
@base_url = 'https://time.puzzle.ch'
|
@@ -23,26 +23,52 @@ module Gpuzzletime
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def run
|
26
|
-
|
26
|
+
case @command
|
27
|
+
when :show
|
28
|
+
fill_entries(@command)
|
29
|
+
entries.each do |date, entries|
|
30
|
+
puts date, '----------'
|
31
|
+
entries.each do |entry|
|
32
|
+
puts entry
|
33
|
+
end
|
34
|
+
puts nil
|
35
|
+
end
|
36
|
+
when :upload
|
37
|
+
fill_entries(@command)
|
38
|
+
entries.each do |date, entries|
|
39
|
+
puts "Uploading #{date}"
|
40
|
+
entries.each do |start, entry|
|
41
|
+
open_browser(start, entry)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
when :edit
|
45
|
+
launch_editor
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
27
50
|
|
28
|
-
|
51
|
+
def entries
|
52
|
+
@entries ||= {}
|
53
|
+
end
|
29
54
|
|
30
|
-
|
55
|
+
def fill_entries(purpose)
|
56
|
+
parse(read).each do |date, lines|
|
31
57
|
# this is mixing preparation, assembly and output, but gets the job done
|
32
58
|
next unless date # guard against the machine
|
33
59
|
next unless @date == :all || @date == date # limit to one day if passed
|
34
|
-
|
60
|
+
entries[date] = []
|
35
61
|
|
36
62
|
start = nil # at the start of the day, we have no previous end
|
37
63
|
|
38
|
-
|
64
|
+
lines.each do |entry|
|
39
65
|
finish = entry[:time] # we use that twice
|
40
66
|
hidden = entry[:description].match(/\*\*$/) # hide lunch and breaks
|
41
67
|
|
42
68
|
if start && !hidden
|
43
|
-
case
|
69
|
+
case purpose # assemble data according to command
|
44
70
|
when :show
|
45
|
-
|
71
|
+
entries[date] << [
|
46
72
|
start, '-', finish,
|
47
73
|
[
|
48
74
|
entry[:ticket],
|
@@ -52,35 +78,15 @@ module Gpuzzletime
|
|
52
78
|
].compact.join(' ∴ '),
|
53
79
|
].compact.join(' ')
|
54
80
|
when :upload
|
55
|
-
|
81
|
+
entries[date] << [start, entry]
|
56
82
|
end
|
57
83
|
end
|
58
84
|
|
59
85
|
start = finish # store previous ending for nice display of next entry
|
60
86
|
end
|
61
87
|
end
|
62
|
-
|
63
|
-
case @command
|
64
|
-
when :show
|
65
|
-
@entries.each do |date, entries|
|
66
|
-
puts date, '----------'
|
67
|
-
entries.each do |entry|
|
68
|
-
puts entry
|
69
|
-
end
|
70
|
-
puts nil
|
71
|
-
end
|
72
|
-
when :upload
|
73
|
-
@entries.each do |date, entries|
|
74
|
-
puts "Uploading #{date}"
|
75
|
-
entries.each do |start, entry|
|
76
|
-
open_browser(start, entry)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
88
|
end
|
81
89
|
|
82
|
-
private
|
83
|
-
|
84
90
|
def open_browser(start, entry)
|
85
91
|
url = "#{@base_url}/ordertimes/new?#{url_options(start, entry)}"
|
86
92
|
system "gnome-open '#{url}' > /dev/null 2> /dev/null"
|
@@ -111,6 +117,7 @@ module Gpuzzletime
|
|
111
117
|
case date
|
112
118
|
when 'yesterday' then Date.today.prev_day.to_s
|
113
119
|
when 'today' then Date.today.to_s
|
120
|
+
when 'last' then parse(read).to_h.keys.compact.sort[-2] || Date.today.prev_day.to_s
|
114
121
|
else date
|
115
122
|
end
|
116
123
|
end
|
@@ -125,9 +132,9 @@ module Gpuzzletime
|
|
125
132
|
|
126
133
|
def parse(data)
|
127
134
|
data.split("\n")
|
128
|
-
|
129
|
-
|
130
|
-
|
135
|
+
.map { |line| tokenize(line) }
|
136
|
+
.group_by { |match| match && match[:date] }
|
137
|
+
.to_a
|
131
138
|
end
|
132
139
|
|
133
140
|
def tokenize(line)
|
@@ -142,7 +149,7 @@ module Gpuzzletime
|
|
142
149
|
end
|
143
150
|
|
144
151
|
def parser_file(parser_name)
|
145
|
-
Pathname.new("~/.config/gpuzzletime/parsers/#{parser_name}") # security-hole, prevent relative paths!
|
152
|
+
Pathname.new("~/.config/gpuzzletime/parsers/#{parser_name}") # FIXME: security-hole, prevent relative paths!
|
146
153
|
.expand_path
|
147
154
|
end
|
148
155
|
|
@@ -156,7 +163,8 @@ module Gpuzzletime
|
|
156
163
|
|
157
164
|
return unless parser.exist?
|
158
165
|
|
159
|
-
|
166
|
+
cmd = %(#{parser} "#{entry[:ticket]}" "#{entry[:description]}" #{tags.map(&:inspect).join(' ')})
|
167
|
+
`#{cmd}`.chomp # maybe only execute if parser is in correct dir?
|
160
168
|
end
|
161
169
|
end
|
162
170
|
end
|
data/lib/gpuzzletime/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gpuzzletime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthias Viehweger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: overcommit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.45'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.45'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,7 +89,9 @@ extensions: []
|
|
75
89
|
extra_rdoc_files: []
|
76
90
|
files:
|
77
91
|
- ".gitignore"
|
92
|
+
- ".overcommit.yml"
|
78
93
|
- ".rspec"
|
94
|
+
- ".rubocop.yml"
|
79
95
|
- ".ruby-gemset"
|
80
96
|
- ".ruby-version"
|
81
97
|
- ".travis.yml"
|