logtime 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77ac03824d4a2dbe1375dd8e56f22f2af21eb696
4
- data.tar.gz: 7f501f03833e8df2e86726f57d185294dabec9f8
3
+ metadata.gz: 9322d0f14a4b772705e7289e0d05d55432212dfa
4
+ data.tar.gz: 38c810feb097ec77117048e944c3e787a34843a2
5
5
  SHA512:
6
- metadata.gz: 2d47a4be6bd4297fc27b24c658cdd21a365e8e4e6023527368009a7b14c74c625126dc168bfa64a70bcebd02a266ad19d3550f6693be14edb3fa017e0ea99588
7
- data.tar.gz: 317788fe8cc68ff84d519f0c658701830a4658930d47a3c3b616b88a4613777971ea916c424aef477dd24d8da10293fb612a84fae633bd9440159fdcc4886b1d
6
+ metadata.gz: ab428f98cba504aa37ba07eaa77734aa4dcad4f73bf60bb341f084750249a0bd2c3fa8f2efefbd871a2e7bce01d2580a024ef723e4e4c6a31456b237fcbecdaa
7
+ data.tar.gz: a01dbf14f7a9a224778e70982cc10b748929ae6d1f40f7e52fde03d3028aa962e16e10efdf13ef6dfbe387a3eea759149659d20c5c3a6285cc99412571a0a9c8
checksums.yaml.gz.sig CHANGED
Binary file
data/Gemfile.lock CHANGED
@@ -16,12 +16,11 @@ GEM
16
16
  tzinfo (~> 1.1)
17
17
  arel (5.0.1.20140414130214)
18
18
  builder (3.2.2)
19
- chronic (0.10.2)
20
19
  chronic_duration (0.10.6)
21
20
  numerizer (~> 0.1.1)
22
21
  i18n (0.7.0)
23
- json (1.8.2)
24
- minitest (5.6.1)
22
+ json (1.8.3)
23
+ minitest (5.7.0)
25
24
  numerizer (0.1.1)
26
25
  sqlite3 (1.3.10)
27
26
  thor (0.19.1)
@@ -34,7 +33,6 @@ PLATFORMS
34
33
 
35
34
  DEPENDENCIES
36
35
  activerecord (~> 4.1.6)
37
- chronic (= 0.10.2)
38
36
  chronic_duration (= 0.10.6)
39
37
  sqlite3 (~> 1.3.9)
40
38
  thor (~> 0.19.1)
data/README.md CHANGED
@@ -3,30 +3,32 @@ Logtime
3
3
 
4
4
  Log your time. Get better at time estimation with statistics.
5
5
 
6
+ [![Gem Version](https://badge.fury.io/rb/logtime.svg)](https://rubygems.org/gems/logtime)
7
+
6
8
  ## Install
7
9
 
8
10
  `gem install logtime`
9
11
 
10
- ## Database
11
-
12
- The first time you run Logtime, it will take a few seconds to setup and save a new database.
13
-
14
- By default, Logtime saves a sqlite database file to `~/.logtime/database.db`.
12
+ The first time you run Logtime, it will take a few seconds to setup and save a new database; by default it saves the database file to `~/.logtime/database.db`.
15
13
 
16
14
  ## Getting help
17
15
 
18
- `logtime help` will show all commands, and `logtime help command` will tell you more about the specified command.
16
+ `lt help` will show all commands, and `lt help command` will tell you more about the specified command.
17
+
18
+ `lt add logname` **Add log**
19
19
 
20
- `logtime add logname` **Add log**
20
+ `lt add project --start false` **Add log with out starting it**
21
21
 
22
- `logtime add project --start false` **Do not start on add**
22
+ `lt add '13 James st' --tag construction,work` **Tag log**
23
23
 
24
- `logtime add 'house 5b' --tag construction,work` **Use tags**
24
+ `lt add 'new design' --estimate '2 hours and 25 minutes'` **Provide estimates**
25
25
 
26
- `logtime add 'new design' --estimate '2 hours and 25 minutes'` **Provide estimates**
26
+ `lt start name` **Start log**
27
27
 
28
- `logtime start name` **start**
28
+ `lt stop name` **Stop log**
29
29
 
30
- `logtime stop name` **stop**
30
+ `lt ls work` **List only specifically tagged logs**
31
31
 
32
+ `lt ls --order name` **List logs alphabetically**
32
33
 
34
+ `lt ls --order created_at` **List logs by create date**
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
data/bin/lt ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'logtime'
3
+ LogTime.start(ARGV)
@@ -1,6 +1,8 @@
1
1
  # Application configutation
2
2
  I18n.config.enforce_available_locales = true
3
- Time.zone = 'Brisbane'
4
3
  ActiveRecord::Base.default_timezone = :local
5
4
  ActiveRecord::Base.logger = Logger.new(STDERR)
6
- ActiveRecord::Base.logger.level = 1
5
+ ActiveRecord::Base.logger.level = 1
6
+
7
+ $logtime_path = File.join(File.expand_path('~'), '.logtime')
8
+ $time_display = "%Y-%m-%d %H:%M:%S"
data/config/database.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  ActiveRecord::Base.establish_connection(
2
2
  :adapter => "sqlite3",
3
- :database => File.join($config_path, 'database.db') # or otherwise ":memory:"
3
+ :database => File.join($logtime_path, 'database.db') # or otherwise ":memory:"
4
4
  )
@@ -2,7 +2,6 @@ require 'thor'
2
2
  require 'active_record'
3
3
  require 'sqlite3'
4
4
  require 'chronic_duration'
5
- $config_path = File.join(File.expand_path('~'), '.logtime')
6
- require_relative 'database.rb'
7
5
  require_relative 'application.rb'
6
+ require_relative 'database.rb'
8
7
  require_relative 'schema.rb'
data/config/schema.rb CHANGED
@@ -38,4 +38,4 @@ ActiveRecord::Schema.define do
38
38
  table.timestamps
39
39
  end unless ActiveRecord::Base.connection.table_exists? 'series'
40
40
 
41
- end unless File.exists?(File.join($config_path, 'database.db'))
41
+ end unless File.exists?(File.join($logtime_path, 'database.db'))
data/lib/commands/add.rb CHANGED
@@ -5,7 +5,7 @@ module Commands
5
5
  option :tag, :type => :string, :alias => '-t', default: ""
6
6
  option :estimate, :type => :string, :alias => '-e', default: false
7
7
  option :start, :type => :boolean, default: true
8
- desc "add [NAME]", "create new log"
8
+ desc "add [NAME]", "Create new log"
9
9
  def add(name)
10
10
  log = Log.new(name: name).tag(options[:tag])
11
11
 
@@ -28,8 +28,7 @@ module Commands
28
28
  end
29
29
 
30
30
  # start option
31
- if options[:start]
32
- log.activate if Series.begin(log_id: log.id)
31
+ if options[:start] and log.start!
33
32
  say name.to_s + " added and started", :green
34
33
  else
35
34
  say name.to_s + " added", :green
data/lib/commands/list.rb CHANGED
@@ -3,46 +3,53 @@ module Commands
3
3
  def self.included(thor)
4
4
  thor.class_eval do
5
5
  option :active, :type => :boolean, :default => true
6
- #option :tag, :type => :string, :alias => '-t'
7
- desc "ls", "list time series"
8
- def ls(tag='')
6
+ option :order, :type => :string, :default => "updated_at"
7
+ desc "ls", "List time series"
8
+ def ls(search='')
9
9
  logs = Log.where(active: options[:active]).includes(:series).includes(:tags)
10
- logs = logs.tagged(tag) if !tag.blank?
10
+ logs = logs.order(options[:order].to_sym => :desc)
11
+ logs = logs.tagged(search) if !search.blank?
11
12
 
12
13
  creep_stats = Statistics.new
13
- table = [['#', 'name', 'active', 'tags', 'series', 'time', 'estimate', 'creep %']] # header
14
+ table = [['#', 'name', '', 'tags', 'series', 'time', 'start', 'stop', 'estimate', 'creep %']] # header
14
15
  logs.each do |log|
15
16
 
16
17
  # tags
17
18
  tags = log.tags.map do |t|
18
19
  t.tag
19
20
  end
20
-
21
- # only show logs with tag, if selected
22
- # if !tag.blank?
23
- # next unless tags.include? tag
24
- # end
21
+ tags = tags.join ' '
25
22
 
26
23
  # active text
27
24
  active = "ACTIVE" if log.active == "t"
28
25
 
29
26
  # total counter
30
- total_time = (log.total/3600).round(2)
27
+ total_time = (log.total_time/3600).round(2) # to hours
28
+ total_time = "#{total_time} hours"
29
+
30
+ # first start time
31
+ start = time_display(log.series.first.start) if log.series.first
32
+
33
+ # last stop time
34
+ stop = time_display(log.series.last.end) if log.series.last
31
35
 
32
- # estimation creep
36
+ # estimation and creep
33
37
  if log.estimation
34
- creep = (total_time/log.estimation)*100
38
+ creep = log.creep # creep %
35
39
  creep_stats << creep
36
- creep = creep.round(3)
37
- estimation = (log.estimation/3600).round(3) # log estimation to hours
40
+ creep = creep.round(2) # round perecentage
41
+ estimation = (log.estimation/3600).round(2) # estimation to hours
38
42
  end
39
43
 
44
+ # table
40
45
  table << [log.id,
41
46
  log.name,
42
47
  active || '',
43
48
  tags,
44
49
  log.series.count || '',
45
50
  total_time || '',
51
+ start || '',
52
+ stop || '',
46
53
  estimation || '',
47
54
  creep || '']
48
55
  end
@@ -2,25 +2,30 @@ module Commands
2
2
  module Start
3
3
  def self.included(thor)
4
4
  thor.class_eval do
5
- desc "start [NAME]", "start new timer"
5
+ desc "start [NAME]", "Start new timer"
6
6
  def start(name)
7
+ log = Log.find_by(name: name)
7
8
 
8
9
  # not found
9
- if Log.where(name: name).count == 0
10
- say name.to_s + " not found", :red
10
+ if !log
11
+ say "#{name} not found", :red
11
12
  exit
12
13
  end
13
14
 
14
- log = Log.find_by(name: name)
15
-
16
15
  # already active?
17
- if log.active == "t"
18
- say name.to_s + " already active", :red
16
+ if log.active?
17
+ say "#{name} already active", :red
19
18
  exit
20
19
  end
21
20
 
22
21
  # begin new series, activate log
23
- series = Series.begin(log_id: log.id) and log.activate
22
+ # Series.start!(log_id: log.id)
23
+ if log.start!
24
+ started_at = time_display(Time.now)
25
+ say "#{name} started at #{started_at}", :green
26
+ else
27
+ say "#{name} failed to start", :red
28
+ end
24
29
  end
25
30
  end
26
31
  end
data/lib/commands/stop.rb CHANGED
@@ -2,25 +2,34 @@ module Commands
2
2
  module Stop
3
3
  def self.included(thor)
4
4
  thor.class_eval do
5
- desc "stop [NAME]", "stop active timer"
5
+ desc "stop [NAME]", "Stop active timer"
6
6
  def stop(name)
7
- if Log.where(name: name).count == 0
7
+ log = Log.find_by(name: name)
8
+
9
+ # not found
10
+ if !log
8
11
  say name.to_s + " not found", :red
9
12
  exit
10
13
  end
11
14
 
12
- log = Log.find_by(name: name)
13
- if log.active == "f"
14
- say name.to_s + " not active", :red
15
+ # log not active
16
+ if log.inactive?
17
+ say "#{name} not active", :red
15
18
  exit
16
19
  end
17
20
 
18
- series = log.series.last
19
- if series.stop and log.deactivate
20
- say name + " stopped!", :green
21
+ # stop log
22
+ if log.stop!
23
+ say "#{name} stopped!", :green
21
24
 
22
- # this_series = log.series.last
23
- say (series.total/3600).round(3).to_s + " hours out of " + (log.total/3600).round(3).to_s, :cyan
25
+ time_total = log.total_time/3600
26
+ time_total = time_total.round(2)
27
+ time_last = Series.find(log.series.last.id).total_time/3600
28
+ time_last = time_last.round(2)
29
+ # time_start =
30
+ say "#{time_last} hours out of #{time_total}", :cyan
31
+ else
32
+ say "#{name} failed to stop", :red
24
33
  end
25
34
  end
26
35
  end
@@ -1,5 +1,5 @@
1
1
  module TimeDisplayHelper
2
- def display_time(time)
3
- time.strftime("%H:%M:%S %d/%m/%y") if time.is_a? Time
2
+ def time_display(time)
3
+ time.strftime($time_display || "%Y-%m-%d %H:%M:%S") if time.is_a? Time
4
4
  end
5
5
  end
data/lib/models/log.rb CHANGED
@@ -10,7 +10,10 @@ class Log < ActiveRecord::Base
10
10
 
11
11
  validates :name, uniqueness: true
12
12
 
13
- has_many :series
13
+ #
14
+ # Tags
15
+ #
16
+
14
17
  has_and_belongs_to_many :tags
15
18
 
16
19
  def tag(tags)
@@ -21,27 +24,97 @@ class Log < ActiveRecord::Base
21
24
  return self
22
25
  end
23
26
 
24
- def tagged(tag)
27
+ #
28
+ # Series
29
+ #
30
+
31
+ has_many :series
32
+
33
+ #
34
+ # Stop
35
+ #
36
+
37
+ def stop
38
+ self.deactivate
39
+ self.series.last.stop!
40
+ end
25
41
 
42
+ def stop!
43
+ self.stop
44
+ self.save!
26
45
  end
27
46
 
47
+ #
48
+ # Start
49
+ #
50
+
51
+ def start(options={})
52
+ self.activate
53
+
54
+ attributes = {
55
+ start: Time.now
56
+ }.merge! options
57
+
58
+ self.series << Series.new(attributes)
59
+ end
60
+
61
+ def start!(options={})
62
+ self.start(options)
63
+ self.save!
64
+ end
65
+
66
+ #
67
+ # Activate
68
+ #
69
+
28
70
  def activate
29
71
  self.active = true
30
- self.save
31
72
  end
32
73
 
74
+ def activate!
75
+ self.activate
76
+ self.save!
77
+ end
78
+
79
+ def active?
80
+ self.active == "t"
81
+ end
82
+
83
+ #
84
+ # Deactivate
85
+ #
86
+
33
87
  def deactivate
34
88
  self.active = false
35
- self.save
36
89
  end
37
90
 
38
- def total
91
+ def deactivate!
92
+ self.active = false
93
+ self.save!
94
+ end
95
+
96
+ def inactive?
97
+ self.active == "f"
98
+ end
99
+
100
+ #
101
+ # Total time
102
+ #
103
+
104
+ def total_time
39
105
  difference = 0
40
106
  self.series.each do |s|
41
107
  ending = s.end || Time.now
42
- # next unless s.start and s.end
43
108
  difference = difference + s.start.difference(ending)
44
109
  end
45
110
  difference
46
111
  end
112
+
113
+ #
114
+ # Creep
115
+ #
116
+
117
+ def creep
118
+ self.total_time/self.estimation
119
+ end
47
120
  end
data/lib/models/series.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  class Series < ActiveRecord::Base
6
6
  belongs_to :log
7
7
 
8
- def self.begin(options = {})
8
+ def self.start!(options = {})
9
9
  attributes = {
10
10
  start: Time.now
11
11
  }.merge! options
@@ -13,12 +13,12 @@ class Series < ActiveRecord::Base
13
13
  create(attributes)
14
14
  end
15
15
 
16
- def begin
16
+ def start!
17
17
  self.start = Time.now
18
18
  self.save
19
19
  end
20
20
 
21
- def stop
21
+ def stop!
22
22
  self.end = Time.now
23
23
  self.save
24
24
  end
@@ -27,9 +27,8 @@ class Series < ActiveRecord::Base
27
27
  !self.end.blank?
28
28
  end
29
29
 
30
- def total
31
- return false if self.end.blank? or self.start.blank?
30
+ def total_time
32
31
 
33
- self.start.difference(self.end)
32
+ self.start.difference(self.end || Time.now)
34
33
  end
35
34
  end
@@ -1,6 +1,6 @@
1
1
  module SubCommands
2
2
  class Series < Thor
3
- desc "ls", "list series"
3
+ desc "ls", "List all series"
4
4
  option :order, :type => :string, :default => "updated_at"
5
5
  def ls
6
6
  series = ::Series.all.order(options[:order].to_sym => :desc)
@@ -16,13 +16,14 @@ module SubCommands
16
16
  # total time
17
17
  series_stats << timer = start.difference(finish || Time.now)
18
18
 
19
- start = display_time(start) if start
20
- finish = display_time(finish) if finish
19
+ start = time_display(start) if start
20
+ finish = time_display(finish) if finish
21
21
 
22
22
  table << [s.id,
23
- Log.find(s.log_id).name,
24
- start, finish || "active",
25
- (timer/3600).round(2).to_s] # row
23
+ s.log.name,
24
+ start,
25
+ finish || "active",
26
+ (timer/3600).round(2).to_s] # row
26
27
  end
27
28
 
28
29
  puts ''
@@ -33,27 +34,27 @@ module SubCommands
33
34
  say [(series_stats.mean/3600).round(2), " hours avg"].join(' '), :cyan
34
35
  end
35
36
 
36
- desc "rm [ID]", "remove series"
37
+ desc "rm [ID]", "Destroy series"
37
38
  option :confirm, :type => :boolean, :default => false, :alias => '-y'
38
39
  def rm(id)
39
- if ::Series.where(id: id).count == 0
40
- say "Series #" + id.to_s + " not found", :red
40
+ series = ::Series.find(id)
41
+
42
+ if !series
43
+ say "Series ##{id} not found", :red
41
44
  exit
42
45
  end
43
46
 
44
- series = ::Series.find(id)
45
-
46
47
  if !options[:confirm]
47
- say "You must --confirm before removing this series", :red
48
+ say "You must --confirm before removing series", :red
48
49
  exit
49
50
  end
50
51
 
51
52
  if !series.finished?
52
- series.log.deactivate
53
+ series.log.deactivate!
53
54
  end
54
55
 
55
56
  destroyed = series.destroy
56
- say "Series #" + id.to_s + " has been destroyed", :green
57
+ say "Series ##{id} has been destroyed", :green
57
58
  end
58
59
  end
59
60
  end
@@ -1,6 +1,6 @@
1
1
  module SubCommands
2
2
  class Tags < Thor
3
- desc "add", "create new tag"
3
+ desc "add", "Create new tag"
4
4
  def add(tag)
5
5
  tag = ::Tag.new(tag: tag.strip)
6
6
 
@@ -14,7 +14,7 @@ module SubCommands
14
14
  say tag.tag + " added!", :green
15
15
  end
16
16
 
17
- desc "rm", "remove tag"
17
+ desc "rm", "Destroy tag"
18
18
  # option :prune, :type => :boolean, :alias => '-p', :default => false not implemented yet
19
19
  def rm(tag)
20
20
  tag = ::Tag.find_by!(tag: tag)
@@ -22,7 +22,7 @@ module SubCommands
22
22
  say ["Tag", tag.tag, "destroyed forever"].join(' '), :green
23
23
  end
24
24
 
25
- desc "ls", "list all tags"
25
+ desc "ls", "List all tags"
26
26
  option :order, :type => :string, :default => "created_at"
27
27
  def ls
28
28
  tags = ::Tag.order(options[:order].to_sym => :desc)
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paperback
@@ -94,6 +94,7 @@ description: |2
94
94
  email: sam@samwhat.com
95
95
  executables:
96
96
  - logtime
97
+ - lt
97
98
  extensions: []
98
99
  extra_rdoc_files: []
99
100
  files:
@@ -104,31 +105,17 @@ files:
104
105
  - README.md
105
106
  - VERSION
106
107
  - bin/logtime
108
+ - bin/lt
107
109
  - certs/paperback.pem
108
110
  - config/application.rb
109
111
  - config/database.rb
110
112
  - config/initialisation.rb
111
113
  - config/schema.rb
112
- - lib/app/commands/add.rb
113
- - lib/app/commands/list.rb
114
- - lib/app/commands/start.rb
115
- - lib/app/commands/stop.rb
116
- - lib/app/helpers/estimate.rb
117
- - lib/app/helpers/statistics.rb
118
- - lib/app/helpers/time_to_words.rb
119
- - lib/app/logtime.rb
120
- - lib/app/models/log.rb
121
- - lib/app/models/series.rb
122
- - lib/app/models/tag.rb
123
- - lib/app/subcommands/keyword.rb
124
- - lib/app/subcommands/series.rb
125
- - lib/app/subcommands/tags.rb
126
114
  - lib/commands/add.rb
127
115
  - lib/commands/list.rb
128
116
  - lib/commands/start.rb
129
117
  - lib/commands/stop.rb
130
118
  - lib/commands/version.rb
131
- - lib/helpers/estimate.rb
132
119
  - lib/helpers/statistics.rb
133
120
  - lib/helpers/time_difference.rb
134
121
  - lib/helpers/time_display.rb
@@ -137,7 +124,6 @@ files:
137
124
  - lib/models/log.rb
138
125
  - lib/models/series.rb
139
126
  - lib/models/tag.rb
140
- - lib/subcommands/keyword.rb
141
127
  - lib/subcommands/series.rb
142
128
  - lib/subcommands/tags.rb
143
129
  - logtime.gemspec
metadata.gz.sig CHANGED
Binary file
@@ -1,41 +0,0 @@
1
- module Commands
2
- module Add
3
- def self.included(thor)
4
- thor.class_eval do
5
- option :tag, :type => :string, :alias => '-t', default: ""
6
- option :estimate, :type => :string, :alias => '-e', default: false
7
- option :start, :type => :boolean, default: true
8
- desc "add [NAME]", "create new log"
9
- def add(name)
10
- log = Log.new(name: name).tag(options[:tag])
11
-
12
- # estimate option
13
- if options[:estimate]
14
- estimation = ChronicDuration.parse(options[:estimate]) if !estimation
15
- if !estimation
16
- say "could not parse estimation time: " + options[:estimate], :red
17
- exit
18
- end
19
- log.estimation = estimation
20
- end
21
-
22
- # save log
23
- if !log.save
24
- log.errors.full_messages.each do |error|
25
- say error, :red
26
- end
27
- exit
28
- end
29
-
30
- # start option
31
- if options[:start]
32
- log.activate if Series.begin(log_id: log.id)
33
- say name.to_s + " added and started", :green
34
- else
35
- say name.to_s + " added", :green
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end