toggl-worktime 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d7d312022057b262ea569daa0ff5a2d4fd81f515c6c0fbe32d4dbbac1d5f8bd
4
- data.tar.gz: 2412b9d69c4a482400bde188a1a7523b215c63891f1d7159a7834b257cb673b8
3
+ metadata.gz: f726845f28a920e1348ee0fd4fc2b136a6394b8f4007ea8498095b6eddc39e5a
4
+ data.tar.gz: e820f632627f8b8b137008cb48b4a9678ec14682aef3256750ccb8367a4a7d65
5
5
  SHA512:
6
- metadata.gz: a643c84a3603192a66519cc95cf40523ff98bb626702608f958b9494b2ec8fd6c5551554c18cfac95ac71099a6936553361263e5471cecd7e0c1c2c4616cd79b
7
- data.tar.gz: 6f1c575654a741742f3e4efcf438fa0ac89bed10b68b685e2aed44b2e4fe5bbbb292b67ff17dc10fa828acb1c2e133133ac3803cb07812b9f8ccde7d7b444b3c
6
+ metadata.gz: 4352863b125a2315ded1ec35702f0a04976fd2a3957ad0fd16a487251a98869f653de2fa01931a81e77c8a05950fafc4e56fe2cde32745b3d673d0ae430f91ce
7
+ data.tar.gz: d890b93dc1664bf686c5a36cbc271b24a5f7b95fc66b02a4a9bfa40cfb35d301e01feb89eb46e4fd8d9462d91c4daf89a904a31e3ab8343ba21b3f6a8d290f8d
data/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ # Change Log
2
+
3
+ ## [v0.3.0](https://github.com/limitusus/toggl-worktime/tree/v0.3.0) (2018-08-01)
4
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.2.0...v0.3.0)
5
+
6
+ **Closed issues:**
7
+
8
+ - ignore vacation tag [\#3](https://github.com/limitusus/toggl-worktime/issues/3)
9
+
10
+ **Merged pull requests:**
11
+
12
+ - Config YAML [\#5](https://github.com/limitusus/toggl-worktime/pull/5) ([limitusus](https://github.com/limitusus))
13
+ - Specify year [\#4](https://github.com/limitusus/toggl-worktime/pull/4) ([limitusus](https://github.com/limitusus))
14
+
15
+ ## [v0.2.0](https://github.com/limitusus/toggl-worktime/tree/v0.2.0) (2018-04-02)
16
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.8...v0.2.0)
17
+
18
+ **Merged pull requests:**
19
+
20
+ - Remove const [\#2](https://github.com/limitusus/toggl-worktime/pull/2) ([limitusus](https://github.com/limitusus))
21
+
22
+ ## [v0.1.8](https://github.com/limitusus/toggl-worktime/tree/v0.1.8) (2018-04-01)
23
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.7...v0.1.8)
24
+
25
+ **Merged pull requests:**
26
+
27
+ - Export work\_time from driver [\#1](https://github.com/limitusus/toggl-worktime/pull/1) ([limitusus](https://github.com/limitusus))
28
+
29
+ ## [v0.1.7](https://github.com/limitusus/toggl-worktime/tree/v0.1.7) (2017-09-19)
30
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.6...v0.1.7)
31
+
32
+ ## [v0.1.6](https://github.com/limitusus/toggl-worktime/tree/v0.1.6) (2017-09-19)
33
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.5...v0.1.6)
34
+
35
+ ## [v0.1.5](https://github.com/limitusus/toggl-worktime/tree/v0.1.5) (2017-08-15)
36
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.4...v0.1.5)
37
+
38
+ ## [v0.1.4](https://github.com/limitusus/toggl-worktime/tree/v0.1.4) (2017-07-07)
39
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.3...v0.1.4)
40
+
41
+ ## [v0.1.3](https://github.com/limitusus/toggl-worktime/tree/v0.1.3) (2017-07-07)
42
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.2...v0.1.3)
43
+
44
+ ## [v0.1.2](https://github.com/limitusus/toggl-worktime/tree/v0.1.2) (2017-07-05)
45
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.1...v0.1.2)
46
+
47
+ ## [v0.1.1](https://github.com/limitusus/toggl-worktime/tree/v0.1.1) (2017-07-05)
48
+ [Full Changelog](https://github.com/limitusus/toggl-worktime/compare/v0.1.0...v0.1.1)
49
+
50
+ ## [v0.1.0](https://github.com/limitusus/toggl-worktime/tree/v0.1.0) (2017-07-05)
51
+
52
+
53
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
data/README.md CHANGED
@@ -13,6 +13,17 @@ worktime
13
13
  2017-06-12 13:29:09 - 2017-06-12 19:23:23
14
14
  ```
15
15
 
16
+ or you can specify year (default is "this" year)
17
+
18
+ ```console
19
+ $ toggl-worktime 2017 6 12
20
+ Tomoya Kabe
21
+ worktime
22
+ 2017-06-12 09:54:34 - 2017-06-12 12:40:45
23
+ 2017-06-12 13:29:09 - 2017-06-12 19:23:23
24
+ ```
25
+
26
+
16
27
  Weekend
17
28
 
18
29
  ```console
@@ -50,6 +61,36 @@ abcdef0123456789
50
61
 
51
62
  You can get your API token from Toggl at your profile settings page.
52
63
 
64
+ NOTE: as of togglv8 v1.2.1, `.toggl` file **MUST NOT** end with a newline (`\010` or LF).
65
+ The recommended way to create the file is `echo -n 'YOUR_TOGGL_API_TOKEN' > ~/.toggl`.
66
+ This issue [will be fixed in the next togglv8 release](https://github.com/kanet77/togglv8/pull/21).
67
+
68
+ ### Configuration
69
+
70
+ Place configuration file in `~/.toggl_worktime`.
71
+ Or you can specify your favorite path with `-c CONFIG` option.
72
+
73
+ ```
74
+ # -*- yaml -*-
75
+
76
+ # working time interval within <working_interval_min> minutes is ignored
77
+ working_interval_min: 10
78
+ # Split the day at <day_begin_hour> o'clock
79
+ day_begin_hour: 6
80
+ # Timezone
81
+ timezone: Asia/Tokyo
82
+
83
+ # Time entries which match the condition below will not be counted as working time
84
+ # Multiple conditions can be specified as an array in top level,
85
+ # multiple keys (only "tags" for now) can be specified as hash keys in a condition,
86
+ # and multiple values can be specifeid as an array.
87
+ # Array conditions will be treated as "OR"
88
+ # Hash conditions will be treated as "AND"
89
+ ignore_conditions:
90
+ - tags:
91
+ - vacation
92
+ ```
93
+
53
94
  ### Just run
54
95
 
55
96
  ```console
data/exe/toggl-worktime CHANGED
@@ -3,22 +3,33 @@
3
3
 
4
4
  $LOAD_PATH << File.expand_path("#{File.dirname __FILE__}/../lib")
5
5
 
6
+ require 'optparse'
6
7
  require 'rubygems'
7
8
  require 'toggl/worktime'
8
9
 
9
10
  Version = Toggl::Worktime::VERSION
10
- MAX_WORKING_INTERVAL = 10
11
- DAY_BEGIN_HOUR = 6
12
- DEFAULT_TIMEZONE = 'Asia/Tokyo'
13
-
14
- driver = Toggl::Worktime::Driver.new(max_working_interval: MAX_WORKING_INTERVAL)
15
-
16
- month = ARGV[0].to_i
17
- day = ARGV[1].to_i
18
- hour = DAY_BEGIN_HOUR
19
- timezone = DEFAULT_TIMEZONE
20
-
21
- driver.merge!(month, day, hour, timezone)
11
+ config_file = "#{ENV['HOME']}/.toggl_worktime"
12
+ debug = false
13
+
14
+ opt = OptionParser.new
15
+ opt.on('-c CONFIG', '--config CONFIG') { |v| config_file = v }
16
+ opt.on('--debug') { |v| debug = v }
17
+ opt.parse!(ARGV)
18
+
19
+ config = Toggl::Worktime::Config.new(path: config_file)
20
+ driver = Toggl::Worktime::Driver.new(config: config)
21
+ p config if debug
22
+
23
+ if ARGV.size == 3
24
+ year, month, day = *ARGV.map(&:to_i)
25
+ elsif ARGV.size == 2
26
+ year = Time.now.year
27
+ month, day = *ARGV.map(&:to_i)
28
+ else
29
+ raise ArgumentError, 'Usage: toggl-worktime [YEAR] MONTH DAY'
30
+ end
31
+
32
+ driver.merge!(year, month, day)
22
33
  user = driver.me
23
34
 
24
35
  puts user['fullname']
@@ -3,6 +3,7 @@
3
3
  require 'togglv8'
4
4
  require 'json'
5
5
  require 'toggl/worktime/version'
6
+ require 'toggl/worktime/config'
6
7
  require 'toggl/worktime/merger'
7
8
  require 'toggl/worktime/time'
8
9
  require 'toggl/worktime/driver'
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module Toggl
6
+ module Worktime
7
+ # Config for Toggl::Worktime
8
+ class Config
9
+ attr_accessor :foo
10
+
11
+ ATTRS = %i[
12
+ working_interval_min
13
+ day_begin_hour
14
+ timezone
15
+ ignore_conditions
16
+ ].freeze
17
+
18
+ ATTR_DEFAULTS = {
19
+ working_interval_min: 10,
20
+ day_begin_hour: 6,
21
+ timezone: 'Asia/Tokyo',
22
+ ignore_conditions: []
23
+ }.freeze
24
+
25
+ ATTRS.each do |attr|
26
+ attr_accessor attr
27
+ end
28
+
29
+ def initialize(args)
30
+ c = self.class.load_config(args[:path])
31
+ attr_set(c)
32
+ end
33
+
34
+ class << self
35
+ def load_config(path)
36
+ YAML.safe_load(File.open(path).read).transform_keys(&:to_sym)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def attr_set(hash)
43
+ ATTRS.each do |k|
44
+ send((k.to_s + '=').to_sym, hash.key?(k) ? hash[k] : ATTR_DEFAULTS[k])
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -4,31 +4,52 @@ module Toggl
4
4
  module Worktime
5
5
  # Toggle API driver
6
6
  class Driver
7
+ ONE_DAY_SECONDS = 86_400
8
+
7
9
  attr_reader :toggl
8
10
  attr_reader :work_time
9
11
 
10
- def initialize(max_working_interval: 10)
12
+ def initialize(config:)
11
13
  @toggl = TogglV8::API.new
12
- @max_working_interval = max_working_interval
14
+ @config = config
13
15
  @merger = nil
14
16
  @work_time = nil
17
+ @zone_offset = Toggl::Worktime::Time.zone_offset(@config.timezone)
18
+ end
19
+
20
+ def time_entries(year, month, day)
21
+ beginning_day = ::Time.new(
22
+ year, month, day, @config.day_begin_hour, 0, 0, @zone_offset
23
+ )
24
+ ending_day = beginning_day + ONE_DAY_SECONDS
25
+ start_iso = beginning_day.strftime('%FT%T%:z')
26
+ end_iso = ending_day.strftime('%FT%T%:z')
27
+ toggl.get_time_entries(start_date: start_iso, end_date: end_iso)
15
28
  end
16
29
 
17
- def time_entries(month, day, hour, timezone)
18
- now = DateTime.now
19
- offset = Toggl::Worktime::Time.zone_offset(timezone)
20
- beginning_day = DateTime.new(now.year, month, day, hour, 0, 0, offset)
21
- ending_day = beginning_day + 1
22
- toggl.get_time_entries(start_date: beginning_day.iso8601, end_date: ending_day.iso8601)
30
+ # time_entries filter with @config.ignore_conditions
31
+ def filter_entries(entries)
32
+ pass_l = lambda { |entry|
33
+ @config.ignore_conditions.none? do |cond|
34
+ cond.keys.all? do |key|
35
+ case key
36
+ when 'tags'
37
+ entry['tags']&.any? { |t| cond[key].include?(t) }
38
+ end
39
+ end
40
+ end
41
+ }
42
+ entries.select { |e| pass_l.call(e) }
23
43
  end
24
44
 
25
45
  def me
26
46
  @toggl.me(true)
27
47
  end
28
48
 
29
- def merge!(month, day, hour, timezone)
30
- time_entries = time_entries(month, day, hour, timezone)
31
- @merger = Toggl::Worktime::Merger.new(time_entries, timezone, @max_working_interval)
49
+ def merge!(year, month, day)
50
+ time_entries = time_entries(year, month, day)
51
+ time_entries = filter_entries(time_entries)
52
+ @merger = Toggl::Worktime::Merger.new(time_entries, @config)
32
53
  @work_time = @merger.merge
33
54
  end
34
55
 
@@ -40,17 +61,16 @@ module Toggl
40
61
  end
41
62
  end
42
63
 
43
- def time_expr(t)
44
- t ? t.strftime('%F %T') : 'nil'
64
+ def time_expr(time)
65
+ time ? time.getlocal(@zone_offset).strftime('%F %T') : 'nil'
45
66
  end
46
67
 
47
68
  def total_time
48
- time = @merger.total_time
49
- total_seconds = (time * 86400).to_i
69
+ total_seconds = @merger.total_time.to_i
50
70
  hours = total_seconds / (60 * 60)
51
71
  minutes = (total_seconds - (hours * 60 * 60)) / 60
52
72
  seconds = total_seconds % 60
53
- format("%02d:%02d:%02d", hours, minutes, seconds)
73
+ format('%02d:%02d:%02d', hours, minutes, seconds)
54
74
  end
55
75
  end
56
76
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'time'
4
+
3
5
  module Toggl
4
6
  module Worktime
5
7
  # Time-entries merger
@@ -8,10 +10,9 @@ module Toggl
8
10
 
9
11
  ONE_DAY_MINUTES = 24 * 60
10
12
 
11
- def initialize(time_entries, timezone, max_working_interval)
13
+ def initialize(time_entries, config)
12
14
  @time_entries = time_entries
13
- @timezone = timezone
14
- @max_working_interval = max_working_interval
15
+ @config = config
15
16
  @current_start = nil
16
17
  @current_stop = nil
17
18
  @continuing = true
@@ -35,7 +36,7 @@ module Toggl
35
36
  end
36
37
 
37
38
  def time_entries_each
38
- zone_offset = Toggl::Worktime::Time.zone_offset(@timezone)
39
+ zone_offset = Toggl::Worktime::Time.zone_offset(@config.timezone)
39
40
  @time_entries.each do |te|
40
41
  start = parse_date(te['start'], zone_offset)
41
42
  stop = parse_date(te['stop'], zone_offset)
@@ -43,7 +44,7 @@ module Toggl
43
44
  @current_start = start if @current_start.nil?
44
45
  @current_stop = stop if @current_stop.nil?
45
46
  if start.nil? || stop.nil?
46
- warn "start or stop time is nil: total time may be incomplete"
47
+ warn 'start or stop time is nil: total time may be incomplete'
47
48
  else
48
49
  @total_time += stop - start
49
50
  end
@@ -53,13 +54,13 @@ module Toggl
53
54
 
54
55
  def parse_date(date, zone_offset)
55
56
  return nil if date.nil?
56
- DateTime.parse(date).new_offset(zone_offset)
57
+ ::Time.parse(date).getlocal(zone_offset)
57
58
  end
58
59
 
59
60
  def continuing(start)
60
61
  return true if @current_stop.nil?
61
62
  interval = (start - @current_stop) * ONE_DAY_MINUTES
62
- @continuing = interval < @max_working_interval
63
+ @continuing = interval < @config.working_interval_min
63
64
  end
64
65
  end
65
66
  end
@@ -4,11 +4,11 @@ module Toggl
4
4
  module Worktime
5
5
  # Timezone
6
6
  module Time
7
- # rational
7
+ # Seconds
8
8
  def self.zone_offset(timezone)
9
9
  tz = ENV['TZ']
10
10
  ENV['TZ'] = timezone
11
- offset = DateTime.now.offset
11
+ offset = ::Time.now.utc_offset
12
12
  ENV['TZ'] = tz
13
13
  offset
14
14
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Toggl
4
4
  module Worktime
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  end
@@ -1,7 +1,6 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
- lib = File.expand_path('../lib', __FILE__)
3
+ lib = File.expand_path('lib', __dir__)
5
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
5
  require 'toggl/worktime/version'
7
6
 
@@ -23,12 +22,12 @@ Gem::Specification.new do |spec|
23
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
23
  spec.require_paths = ['lib']
25
24
 
26
- spec.add_dependency 'togglv8'
27
25
  spec.add_dependency 'awesome_print'
28
- spec.add_development_dependency 'pry'
29
- spec.add_development_dependency 'rb-readline'
30
- spec.add_development_dependency 'rubocop'
26
+ spec.add_dependency 'togglv8'
31
27
  spec.add_development_dependency 'bundler', '~> 1.15'
28
+ spec.add_development_dependency 'pry'
32
29
  spec.add_development_dependency 'rake', '~> 10.0'
30
+ spec.add_development_dependency 'rb-readline'
33
31
  spec.add_development_dependency 'rspec', '~> 3.0'
32
+ spec.add_development_dependency 'rubocop'
34
33
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toggl-worktime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomoya KABE
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-02 00:00:00.000000000 Z
11
+ date: 2018-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: togglv8
14
+ name: awesome_print
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: awesome_print
28
+ name: togglv8
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,21 +39,21 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: pry
42
+ name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '1.15'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '1.15'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rb-readline
56
+ name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,61 +67,61 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rubocop
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '10.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '10.0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: bundler
84
+ name: rb-readline
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '1.15'
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '1.15'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rake
98
+ name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '10.0'
103
+ version: '3.0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '10.0'
110
+ version: '3.0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: rspec
112
+ name: rubocop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '3.0'
117
+ version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: '3.0'
124
+ version: '0'
125
125
  description: Summarise Toggl Time Entries
126
126
  email:
127
127
  - limit.usus@gmail.com
@@ -134,6 +134,7 @@ files:
134
134
  - ".rspec"
135
135
  - ".rubocop.yml"
136
136
  - ".travis.yml"
137
+ - CHANGELOG.md
137
138
  - CODE_OF_CONDUCT.md
138
139
  - Gemfile
139
140
  - LICENSE.txt
@@ -143,6 +144,7 @@ files:
143
144
  - bin/setup
144
145
  - exe/toggl-worktime
145
146
  - lib/toggl/worktime.rb
147
+ - lib/toggl/worktime/config.rb
146
148
  - lib/toggl/worktime/driver.rb
147
149
  - lib/toggl/worktime/merger.rb
148
150
  - lib/toggl/worktime/time.rb