logtime 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.gitignore +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +40 -0
- data/LICENSE.md +21 -0
- data/VERSION +1 -0
- data/bin/logtime +3 -0
- data/certs/paperback.pem +21 -0
- data/config/application.rb +6 -0
- data/config/database.rb +4 -0
- data/config/initialisation.rb +8 -0
- data/config/schema.rb +41 -0
- data/lib/app/commands/add.rb +41 -0
- data/lib/app/commands/list.rb +56 -0
- data/lib/app/commands/start.rb +28 -0
- data/lib/app/commands/stop.rb +29 -0
- data/lib/app/helpers/estimate.rb +13 -0
- data/lib/app/helpers/statistics.rb +45 -0
- data/lib/app/helpers/time_to_words.rb +33 -0
- data/lib/app/logtime.rb +67 -0
- data/lib/app/models/log.rb +42 -0
- data/lib/app/models/series.rb +35 -0
- data/lib/app/models/tag.rb +9 -0
- data/lib/app/subcommands/keyword.rb +214 -0
- data/lib/app/subcommands/series.rb +58 -0
- data/lib/app/subcommands/tags.rb +79 -0
- data/lib/commands/add.rb +41 -0
- data/lib/commands/list.rb +67 -0
- data/lib/commands/start.rb +28 -0
- data/lib/commands/stop.rb +29 -0
- data/lib/commands/version.rb +12 -0
- data/lib/helpers/estimate.rb +13 -0
- data/lib/helpers/statistics.rb +48 -0
- data/lib/helpers/time_difference.rb +20 -0
- data/lib/helpers/time_display.rb +5 -0
- data/lib/helpers/time_to_words.rb +33 -0
- data/lib/logtime.rb +68 -0
- data/lib/models/log.rb +47 -0
- data/lib/models/series.rb +35 -0
- data/lib/models/tag.rb +9 -0
- data/lib/subcommands/keyword.rb +214 -0
- data/lib/subcommands/series.rb +59 -0
- data/lib/subcommands/tags.rb +37 -0
- data/logtime.gemspec +23 -0
- data.tar.gz.sig +2 -0
- metadata +167 -0
- metadata.gz.sig +0 -0
data/lib/logtime.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative '../config/initialisation'
|
2
|
+
|
3
|
+
# require models
|
4
|
+
models = File.expand_path(File.join('..', 'models'), __FILE__)
|
5
|
+
if Dir.exists?(models)
|
6
|
+
Dir.entries(models).each do |file|
|
7
|
+
require File.join(models, file) if file =~ /^(.*)\.rb$/
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# require helpers
|
12
|
+
helpers = File.expand_path(File.join('..', 'helpers'), __FILE__)
|
13
|
+
if Dir.exists?(helpers)
|
14
|
+
Dir.entries(helpers).each do |file|
|
15
|
+
next unless file =~ /^(.*)\.rb$/
|
16
|
+
|
17
|
+
require File.join(helpers, file)
|
18
|
+
|
19
|
+
# helper name
|
20
|
+
load = file.split '_'
|
21
|
+
load = load.each { |h| h.capitalize! }
|
22
|
+
load = load.join
|
23
|
+
load = load[0..-4] # '.rb'
|
24
|
+
load = load + "Helper"
|
25
|
+
|
26
|
+
# load helper
|
27
|
+
begin
|
28
|
+
send(:include, load.constantize)
|
29
|
+
|
30
|
+
rescue
|
31
|
+
ActiveRecord::Base.logger.warn "Failed to load " + load
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# require commands
|
37
|
+
commands = File.expand_path(File.join('..', 'commands'), __FILE__)
|
38
|
+
if Dir.exists?(commands)
|
39
|
+
Dir.entries(commands).each do |file|
|
40
|
+
require_relative File.join(commands, file) if file =~ /^(.*)\.rb$/
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# require subcommands
|
45
|
+
subcommands = File.expand_path(File.join('..', 'subcommands'), __FILE__)
|
46
|
+
if Dir.exists?(subcommands)
|
47
|
+
Dir.entries(subcommands).each do |file|
|
48
|
+
require_relative File.join(subcommands, file) if file =~ /^(.*)\.rb$/
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Application
|
53
|
+
class LogTime < Thor
|
54
|
+
|
55
|
+
# commands
|
56
|
+
include ::Commands::List
|
57
|
+
include ::Commands::Add
|
58
|
+
include ::Commands::Start
|
59
|
+
include ::Commands::Stop
|
60
|
+
include ::Commands::Version
|
61
|
+
|
62
|
+
# subcommands
|
63
|
+
desc "series", ""
|
64
|
+
subcommand "series", SubCommands::Series
|
65
|
+
|
66
|
+
desc "tags", ""
|
67
|
+
subcommand "tags", SubCommands::Tags
|
68
|
+
end
|
data/lib/models/log.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# Logs
|
3
|
+
#
|
4
|
+
|
5
|
+
class Log < ActiveRecord::Base
|
6
|
+
scope :active, -> { where(active: true) }
|
7
|
+
scope :inactive, -> { where(active: false) }
|
8
|
+
scope :tagged, ->(tag) { where(tags: { tag: tag }) }
|
9
|
+
scope :estimated, -> { where("estimation is not null") }
|
10
|
+
|
11
|
+
validates :name, uniqueness: true
|
12
|
+
|
13
|
+
has_many :series
|
14
|
+
has_and_belongs_to_many :tags
|
15
|
+
|
16
|
+
def tag(tags)
|
17
|
+
tags.split(',').each do |t|
|
18
|
+
self.tags << Tag.where(tag: t).first_or_create
|
19
|
+
end
|
20
|
+
|
21
|
+
return self
|
22
|
+
end
|
23
|
+
|
24
|
+
def tagged(tag)
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def activate
|
29
|
+
self.active = true
|
30
|
+
self.save
|
31
|
+
end
|
32
|
+
|
33
|
+
def deactivate
|
34
|
+
self.active = false
|
35
|
+
self.save
|
36
|
+
end
|
37
|
+
|
38
|
+
def total
|
39
|
+
difference = 0
|
40
|
+
self.series.each do |s|
|
41
|
+
ending = s.end || Time.now
|
42
|
+
# next unless s.start and s.end
|
43
|
+
difference = difference + s.start.difference(ending)
|
44
|
+
end
|
45
|
+
difference
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Series
|
3
|
+
#
|
4
|
+
|
5
|
+
class Series < ActiveRecord::Base
|
6
|
+
belongs_to :log
|
7
|
+
|
8
|
+
def self.begin(options = {})
|
9
|
+
attributes = {
|
10
|
+
start: Time.now
|
11
|
+
}.merge! options
|
12
|
+
|
13
|
+
create(attributes)
|
14
|
+
end
|
15
|
+
|
16
|
+
def begin
|
17
|
+
self.start = Time.now
|
18
|
+
self.save
|
19
|
+
end
|
20
|
+
|
21
|
+
def stop
|
22
|
+
self.end = Time.now
|
23
|
+
self.save
|
24
|
+
end
|
25
|
+
|
26
|
+
def finished?
|
27
|
+
!self.end.blank?
|
28
|
+
end
|
29
|
+
|
30
|
+
def total
|
31
|
+
return false if self.end.blank? or self.start.blank?
|
32
|
+
|
33
|
+
self.start.difference(self.end)
|
34
|
+
end
|
35
|
+
end
|
data/lib/models/tag.rb
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
class Keywords < Thor
|
2
|
+
# desc "add <account> <keyword>", "Add a new <keyword> to an <account>"
|
3
|
+
# option :interactive, :type => :boolean, :alias => :i
|
4
|
+
# def add(account, keyword=nil)
|
5
|
+
# account = Account.find_by(:name => account)
|
6
|
+
|
7
|
+
# if account.blank?
|
8
|
+
# say 'no account found', :red
|
9
|
+
# else
|
10
|
+
# if options[:interactive]
|
11
|
+
# say "To stop adding keywords type exit", :cyan
|
12
|
+
# while true
|
13
|
+
# keyword = ask ':'
|
14
|
+
# break if keyword == 'exit'
|
15
|
+
# if Keyword.new(:keyword => keyword, :account_id => account.id).save
|
16
|
+
# say 'added', :green
|
17
|
+
# else
|
18
|
+
# say 'failed', :red
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# else
|
22
|
+
# keyword.split(',').each do |k|
|
23
|
+
# k = Keyword.new(:keyword => k, :account_id => account.id)
|
24
|
+
|
25
|
+
# if k.save
|
26
|
+
# say k.keyword + ' keyword added', :green
|
27
|
+
# else
|
28
|
+
# say 'could not add keyword!', :red
|
29
|
+
# error k.errors.first[0].to_s + ' ' + k.errors.first[1]
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
|
36
|
+
# desc "delete <account> <keyword>", "Removes <keyword> on an <account>"
|
37
|
+
# def delete(account, keyword)
|
38
|
+
# account = Account.search(account)
|
39
|
+
|
40
|
+
# if account.blank?
|
41
|
+
# say 'no account found', :red
|
42
|
+
# else
|
43
|
+
# keyword.split(',').each do |k|
|
44
|
+
# k = Keyword.search(k)
|
45
|
+
|
46
|
+
# if k.blank?
|
47
|
+
# say 'could not find keyword!', :red
|
48
|
+
# else
|
49
|
+
# say k.keyword + ' removed', :green if k.destroy
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
|
55
|
+
# desc "list", "Lists keywords belonging to an <account>"
|
56
|
+
# option :account
|
57
|
+
# def list(account=nil)
|
58
|
+
# if account.nil?
|
59
|
+
# keywords = Keyword.all
|
60
|
+
|
61
|
+
# table = [['# Keyword', '# Position', '']] # header
|
62
|
+
# keywords.each do |k|
|
63
|
+
# stat = k.keyword_statistics.last unless k.keyword_statistics.empty?
|
64
|
+
# table << [k.keyword, stat.position || '', stat.created_at.pretty ] # row
|
65
|
+
# end
|
66
|
+
|
67
|
+
# say ''
|
68
|
+
# print_table table
|
69
|
+
# say ''
|
70
|
+
# else
|
71
|
+
# account = Account.search(account)
|
72
|
+
# if account.blank?
|
73
|
+
# say 'no account found', :red
|
74
|
+
# elsif account.keywords.empty?
|
75
|
+
# say 'no keywords exist for that account yet', :red
|
76
|
+
# else
|
77
|
+
# table = [['# Keyword', '# Position', '']] # header
|
78
|
+
# account.keywords.each do |k|
|
79
|
+
# stat = k.keyword_statistics.last unless k.keyword_statistics.empty?
|
80
|
+
# table << [k.keyword, stat.position || '', stat.created_at.pretty] # row
|
81
|
+
# end
|
82
|
+
|
83
|
+
# say ''
|
84
|
+
# print_table table
|
85
|
+
# say ''
|
86
|
+
# end
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
|
90
|
+
# desc "stats", "Compare keywords over time"
|
91
|
+
# option :search, :default => 'year', :banner => 'year,month,week,day'
|
92
|
+
# option :length, :type => :numeric, :default => 1
|
93
|
+
# option :engine, :default => :google
|
94
|
+
# def stats(account)
|
95
|
+
# account = Account.search(account)
|
96
|
+
|
97
|
+
# if account.blank?
|
98
|
+
# say 'no account found', :red
|
99
|
+
# elsif account.keywords.empty?
|
100
|
+
# say 'no keywords exist for that account yet', :red
|
101
|
+
# else
|
102
|
+
|
103
|
+
# table = [['# Keyword', 'n', 'High', 'Low', 'Current', 'Delta']] # header
|
104
|
+
# searched = 0;
|
105
|
+
# account.keywords.each do |k|
|
106
|
+
# stats = KeywordStatistic.send options[:search], k.id, options[:length], options[:engine]
|
107
|
+
# stats.order(:position)
|
108
|
+
|
109
|
+
# if !stats.empty?
|
110
|
+
# delta = stats.last.position - stats.first.position
|
111
|
+
# delta = '' if delta == 0
|
112
|
+
# table << [k.keyword, stats.size, stats.last.position, stats.first.position, stats.last.position, delta] # row
|
113
|
+
# searched = searched + stats.size
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
|
117
|
+
# if searched == 0
|
118
|
+
# say 'these keywords have not been indexed yet', :red
|
119
|
+
# else
|
120
|
+
# say ''
|
121
|
+
# say account.name + ' has ' + searched.to_s + ' recorded positions for ' + account.keywords.size.to_s + ' keywords', :green
|
122
|
+
# say ''
|
123
|
+
# print_table table
|
124
|
+
# say ''
|
125
|
+
# end
|
126
|
+
# end
|
127
|
+
# end
|
128
|
+
|
129
|
+
# #desc "import", "imports csv file"
|
130
|
+
# #options :file
|
131
|
+
# #def import(file)
|
132
|
+
|
133
|
+
# #end
|
134
|
+
|
135
|
+
# desc "index", "gets keyword position and saves it for later use"
|
136
|
+
# def index(account)
|
137
|
+
# account = Account.search(account)
|
138
|
+
# if account.blank?
|
139
|
+
# say 'no account found', :red
|
140
|
+
# else
|
141
|
+
# table = [['# Keyword', '# Google', '# GoogleUS']] # header
|
142
|
+
# account.keywords.each do |k|
|
143
|
+
# # Google
|
144
|
+
# google = ::Ranking.new(:keyword => k.keyword, :url => account.domain, :limit =>100).from_googleAU
|
145
|
+
# if !google.blank?
|
146
|
+
# KeywordStatistic.new(:keyword_id => k.id, :engine => :google, :position => google).save
|
147
|
+
# say '.', :green, false
|
148
|
+
# else
|
149
|
+
# say '.', :red, false
|
150
|
+
# end
|
151
|
+
|
152
|
+
# # GoogleUS
|
153
|
+
# googleUS = ::Ranking.new(:keyword => k.keyword, :url => account.domain, :limit =>100).from_googleUS
|
154
|
+
# if !googleUS.blank?
|
155
|
+
# KeywordStatistic.new(:keyword_id => k.id, :engine => :googleUS, :position => googleUS).save
|
156
|
+
# say '.', :green, false
|
157
|
+
# else
|
158
|
+
# say '.', :red, false
|
159
|
+
# end
|
160
|
+
|
161
|
+
# # Bing
|
162
|
+
# # bing = ::Ranking.new(:keyword => k.keyword, :url => account.domain, :limit =>100).from_bingAU
|
163
|
+
# # if !bing.blank?
|
164
|
+
# # KeywordStatistic.new(:keyword_id => k.id, :engine => :bing, :position => bing).save
|
165
|
+
# # say '.', :green, false
|
166
|
+
# # else
|
167
|
+
# # say '.', :red, false
|
168
|
+
# # end
|
169
|
+
|
170
|
+
|
171
|
+
# # Yahoo
|
172
|
+
# # yahoo = ::Ranking.new(:keyword => k.keyword, :url => account.domain, :limit =>100).from_yahooAU
|
173
|
+
# # if !yahoo.blank?
|
174
|
+
# # KeywordStatistic.new(:keyword_id => k.id, :engine => :yahoo, :position => yahoo).save
|
175
|
+
# # say '.', :green, false
|
176
|
+
# # else
|
177
|
+
# # say '.', :red, false
|
178
|
+
# # end
|
179
|
+
|
180
|
+
# table << [k.keyword, google, googleUS]
|
181
|
+
# end
|
182
|
+
|
183
|
+
# say ''
|
184
|
+
# print_table table
|
185
|
+
# say ''
|
186
|
+
# end
|
187
|
+
# end
|
188
|
+
|
189
|
+
# desc "export", "export keywords with positions"
|
190
|
+
# option :file
|
191
|
+
# def export(account)
|
192
|
+
# account = Account.search(account)
|
193
|
+
# if account.blank?
|
194
|
+
# say 'no account found', :red
|
195
|
+
# else
|
196
|
+
# table = [['# Date', '# Keyword', '# Position']] # header
|
197
|
+
|
198
|
+
# options[:file] = 'export.csv' unless options.includes? :file
|
199
|
+
# CSV.open(options[:file], 'w') do |csv|
|
200
|
+
# account.keywords.each do |keyword|
|
201
|
+
# keyword.keyword_statistics.each do |stat|
|
202
|
+
# row = [stat.created_at, keyword.keyword, stat.position]
|
203
|
+
# table << row
|
204
|
+
# csv << row
|
205
|
+
# end
|
206
|
+
# end
|
207
|
+
# end
|
208
|
+
|
209
|
+
# say ''
|
210
|
+
# print_table table
|
211
|
+
# say ''
|
212
|
+
# end
|
213
|
+
# end
|
214
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SubCommands
|
2
|
+
class Series < Thor
|
3
|
+
desc "ls", "list series"
|
4
|
+
option :order, :type => :string, :default => "updated_at"
|
5
|
+
def ls
|
6
|
+
series = ::Series.all.order(options[:order].to_sym => :desc)
|
7
|
+
|
8
|
+
series_stats = Statistics.new
|
9
|
+
table = [['#', 'log', 'start', 'end', 'hours']] # header
|
10
|
+
series.each do |s|
|
11
|
+
next if s.log_id.blank?
|
12
|
+
|
13
|
+
start = s.start
|
14
|
+
finish = s.end
|
15
|
+
|
16
|
+
# total time
|
17
|
+
series_stats << timer = start.difference(finish || Time.now)
|
18
|
+
|
19
|
+
start = display_time(start) if start
|
20
|
+
finish = display_time(finish) if finish
|
21
|
+
|
22
|
+
table << [s.id,
|
23
|
+
Log.find(s.log_id).name,
|
24
|
+
start, finish || "active",
|
25
|
+
(timer/3600).round(2).to_s] # row
|
26
|
+
end
|
27
|
+
|
28
|
+
puts ''
|
29
|
+
print_table table
|
30
|
+
puts ''
|
31
|
+
|
32
|
+
say [series.count.to_s, "series out of", ::Series.count].join(' '), :cyan
|
33
|
+
say [(series_stats.mean/3600).round(2), " hours avg"].join(' '), :cyan
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "rm [ID]", "remove series"
|
37
|
+
option :confirm, :type => :boolean, :default => false, :alias => '-y'
|
38
|
+
def rm(id)
|
39
|
+
if ::Series.where(id: id).count == 0
|
40
|
+
say "Series #" + id.to_s + " not found", :red
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
|
44
|
+
series = ::Series.find(id)
|
45
|
+
|
46
|
+
if !options[:confirm]
|
47
|
+
say "You must --confirm before removing this series", :red
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
if !series.finished?
|
52
|
+
series.log.deactivate
|
53
|
+
end
|
54
|
+
|
55
|
+
destroyed = series.destroy
|
56
|
+
say "Series #" + id.to_s + " has been destroyed", :green
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SubCommands
|
2
|
+
class Tags < Thor
|
3
|
+
desc "add", "create new tag"
|
4
|
+
def add(tag)
|
5
|
+
tag = ::Tag.new(tag: tag.strip)
|
6
|
+
|
7
|
+
if !tag.save
|
8
|
+
tag.errors.full_messages.each do |error|
|
9
|
+
say error, :red
|
10
|
+
end
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
say tag.tag + " added!", :green
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "rm", "remove tag"
|
18
|
+
# option :prune, :type => :boolean, :alias => '-p', :default => false not implemented yet
|
19
|
+
def rm(tag)
|
20
|
+
tag = ::Tag.find_by!(tag: tag)
|
21
|
+
tag.destroy
|
22
|
+
say ["Tag", tag.tag, "destroyed forever"].join(' '), :green
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "ls", "list all tags"
|
26
|
+
option :order, :type => :string, :default => "created_at"
|
27
|
+
def ls
|
28
|
+
tags = ::Tag.order(options[:order].to_sym => :desc)
|
29
|
+
|
30
|
+
table = [['#', 'name', 'logs']] # header
|
31
|
+
tags.each do |tag|
|
32
|
+
table << [tag.id, tag.tag, tag.logs.count] # row
|
33
|
+
end
|
34
|
+
print_table table
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/logtime.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'logtime'
|
3
|
+
s.date = '2015-06-03'
|
4
|
+
s.version = `cat VERSION`.strip
|
5
|
+
s.platform = Gem::Platform::RUBY
|
6
|
+
s.description = <<-EOF
|
7
|
+
Tag, record and estimate your time.
|
8
|
+
Get better at time estimation with statistics.
|
9
|
+
EOF
|
10
|
+
s.summary = 'Log your time'
|
11
|
+
s.authors = ['Paperback']
|
12
|
+
s.email = 'sam@samwhat.com'
|
13
|
+
s.files = `git ls-files`.split($RS)
|
14
|
+
s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
|
15
|
+
s.license = 'MIT'
|
16
|
+
s.homepage = 'https://github.com/Paperback/Logtime.git'
|
17
|
+
s.add_runtime_dependency "thor", ["= 0.19.1"]
|
18
|
+
s.add_runtime_dependency "activerecord", ["= 4.1.6"]
|
19
|
+
s.add_runtime_dependency "sqlite3", ["= 1.3.9"]
|
20
|
+
s.add_runtime_dependency "chronic_duration", ["= 0.10.6"]
|
21
|
+
s.cert_chain = ['certs/paperback.pem']
|
22
|
+
s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
|
23
|
+
end
|
data.tar.gz.sig
ADDED
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logtime
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paperback
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDZDCCAkygAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQwwCgYDVQQDDANzYW0x
|
14
|
+
FzAVBgoJkiaJk/IsZAEZFgdzYW13aGF0MRMwEQYKCZImiZPyLGQBGRYDY29tMB4X
|
15
|
+
DTE1MDYwMjA5NTQxOVoXDTE2MDYwMTA5NTQxOVowPDEMMAoGA1UEAwwDc2FtMRcw
|
16
|
+
FQYKCZImiZPyLGQBGRYHc2Ftd2hhdDETMBEGCgmSJomT8ixkARkWA2NvbTCCASIw
|
17
|
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPKKZV2uNAV6W+IlPDriPQNMPp7C
|
18
|
+
Xw7yNlbhmrmgNxJotT4DP6Eyc1NzAJdfz5kQMqgrzxRWBbFD1wPFJB3IdgX1PGKi
|
19
|
+
VOV/BO6sFBFrje/2a364FtKkGjm5V+zyeNZO/DUMuFalnbs+OWvfktFrx2JdBWeU
|
20
|
+
Utmtx3+AcW91+OFZ8y7ZZjUd1FbNP6A+WTYh2odUDFCQXe4xk3bcSGa0Ca7uAfv8
|
21
|
+
VMm1cWu23n+cer1dUW0VspFprSoo/f1WGduZus8PjBFAgEQdDDmTbB49DrigilzT
|
22
|
+
swXvrzGfCKZ0OveVFmhJz1Zr9WUlFNs/GU5x2iQpIZjg1S1mbIfhRhw+H1MCAwEA
|
23
|
+
AaNxMG8wCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFOGu79hFpVdT
|
24
|
+
ALi15MDDorfHC7nPMBoGA1UdEQQTMBGBD3NhbUBzYW13aGF0LmNvbTAaBgNVHRIE
|
25
|
+
EzARgQ9zYW1Ac2Ftd2hhdC5jb20wDQYJKoZIhvcNAQEFBQADggEBAIQ69hz8tXeJ
|
26
|
+
YPTz23tOss7qcY9xo5HInXQXfQ8wZGNVaBPmtBognGO/Kqf5PxeoaZ3FfT8pE9qz
|
27
|
+
giuth+pA2j2EXCBwEuu6+I4J9lfIT030uVMaBIQ1JJxKZcXtRpOP2yd/gKodDVn/
|
28
|
+
KIGKFrb3RWI2VVKNYV7lBCtHyx4uhEBvHmOhHKm3vlkzc+IZWQtCHhJ9iSKSefZ+
|
29
|
+
fZbMJQmYpt4/9KimNcpD+k3mQwMEW947060mRhnpAGkwlIujltb5lQwlWQoKm/Z4
|
30
|
+
2/luIWFCIDih/t3xy/BezkXJLXfRZF2Xd6/Ax9+zEVss6iUJ6kcxwaZ/J5r28EDI
|
31
|
+
KS3vMuAGgck=
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2015-06-03 00:00:00.000000000 Z
|
34
|
+
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: thor
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 0.19.1
|
42
|
+
type: :runtime
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.19.1
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: activerecord
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 4.1.6
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 4.1.6
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: sqlite3
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.3.9
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.3.9
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: chronic_duration
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.10.6
|
84
|
+
type: :runtime
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.10.6
|
91
|
+
description: |2
|
92
|
+
Tag, record and estimate your time.
|
93
|
+
Get better at time estimation with statistics.
|
94
|
+
email: sam@samwhat.com
|
95
|
+
executables:
|
96
|
+
- logtime
|
97
|
+
extensions: []
|
98
|
+
extra_rdoc_files: []
|
99
|
+
files:
|
100
|
+
- ".gitignore"
|
101
|
+
- Gemfile
|
102
|
+
- Gemfile.lock
|
103
|
+
- LICENSE.md
|
104
|
+
- VERSION
|
105
|
+
- bin/logtime
|
106
|
+
- certs/paperback.pem
|
107
|
+
- config/application.rb
|
108
|
+
- config/database.rb
|
109
|
+
- config/initialisation.rb
|
110
|
+
- config/schema.rb
|
111
|
+
- lib/app/commands/add.rb
|
112
|
+
- lib/app/commands/list.rb
|
113
|
+
- lib/app/commands/start.rb
|
114
|
+
- lib/app/commands/stop.rb
|
115
|
+
- lib/app/helpers/estimate.rb
|
116
|
+
- lib/app/helpers/statistics.rb
|
117
|
+
- lib/app/helpers/time_to_words.rb
|
118
|
+
- lib/app/logtime.rb
|
119
|
+
- lib/app/models/log.rb
|
120
|
+
- lib/app/models/series.rb
|
121
|
+
- lib/app/models/tag.rb
|
122
|
+
- lib/app/subcommands/keyword.rb
|
123
|
+
- lib/app/subcommands/series.rb
|
124
|
+
- lib/app/subcommands/tags.rb
|
125
|
+
- lib/commands/add.rb
|
126
|
+
- lib/commands/list.rb
|
127
|
+
- lib/commands/start.rb
|
128
|
+
- lib/commands/stop.rb
|
129
|
+
- lib/commands/version.rb
|
130
|
+
- lib/helpers/estimate.rb
|
131
|
+
- lib/helpers/statistics.rb
|
132
|
+
- lib/helpers/time_difference.rb
|
133
|
+
- lib/helpers/time_display.rb
|
134
|
+
- lib/helpers/time_to_words.rb
|
135
|
+
- lib/logtime.rb
|
136
|
+
- lib/models/log.rb
|
137
|
+
- lib/models/series.rb
|
138
|
+
- lib/models/tag.rb
|
139
|
+
- lib/subcommands/keyword.rb
|
140
|
+
- lib/subcommands/series.rb
|
141
|
+
- lib/subcommands/tags.rb
|
142
|
+
- logtime.gemspec
|
143
|
+
homepage: https://github.com/Paperback/Logtime.git
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata: {}
|
147
|
+
post_install_message:
|
148
|
+
rdoc_options: []
|
149
|
+
require_paths:
|
150
|
+
- lib
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
requirements: []
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 2.4.6
|
164
|
+
signing_key:
|
165
|
+
specification_version: 4
|
166
|
+
summary: Log your time
|
167
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|