Module: Timetrap::CLI
- Extended by:
- CLI, Helpers
- Included in:
- CLI
- Defined in:
- lib/timetrap/cli.rb
Constant Summary
collapse
- USAGE =
<<-EOF
Timetrap - Simple Time Tracking
Usage: #{File.basename $0} COMMAND [OPTIONS] [ARGS...]
COMMAND can be abbreviated. For example `t in` and `t i` are equivalent.
COMMAND is one of:
* archive - Move entries to a hidden sheet (by default named '_[SHEET]') so
they're out of the way.
usage: t archive [--start DATE] [--end DATE] [SHEET]
-s, --start <date:qs> Include entries that start on this date or later
-e, --end <date:qs> Include entries that start on this date or earlier
* backend - Open an sqlite shell to the database.
usage: t backend
* configure - Write out a config file. print path to config file.
usage: t configure
Currently supported options are:
round_in_seconds: The duration of time to use for rounding with
the -r flag
database_file: The file path of the sqlite database
append_notes_delimiter: delimiter used when appending notes via
t edit --append
* display - Display the current timesheet or a specific. Pass `all' as
SHEET to display all sheets.
usage: t display [--ids] [--start DATE] [--end DATE] [--format FMT] [SHEET | all]
-v, --ids Print database ids (for use with edit)
-s, --start <date:qs> Include entries that start on this date or later
-e, --end <date:qs> Include entries that start on this date or earlier
-f, --format <format> The output format. Currently supports ical, csv, and
text (default).
* edit - Alter an entry's note, start, or end time. Defaults to the active entry.
usage: t edit [--id ID] [--start TIME] [--end TIME] [--append] [NOTES]
-i, --id <id:i> Alter entry with id <id> instead of the running entry
-s, --start <time:qs> Change the start time to <time>
-e, --end <time:qs> Change the end time to <time>
-z, --append Append to the current note instead of replacing it
the delimiter between appended notes is
configurable (see configure)
-m, --move <sheet> Move to another sheet
* format - Deprecated: alias for display.
* in - Start the timer for the current timesheet.
usage: t in [--at TIME] [NOTES]
-a, --at <time:qs> Use this time instead of now
* kill - Delete a timesheet or an entry.
usage: t kill [--id ID] [TIMESHEET]
-i, --id <id:i> Alter entry with id <id> instead of the running entry
* list - Show the available timesheets.
usage: t list
* now - Show the status of the current timesheet.
usage: t now
* out - Stop the timer for the current timesheet.
usage: t out [--at TIME]
-a, --at <time:qs> Use this time instead of now
* running - Show all running timesheets.
usage: t running
* switch - Switch to a new timesheet.
usage: t switch TIMESHEET
* week - Shortcut for display with start date set to monday of this week.
usage: t week [--ids] [--end DATE] [--format FMT] [SHEET | all]
OTHER OPTIONS
-h, --help Display this help.
-r, --round Round output to 15 minute start and end times.
-y, --yes Noninteractive, assume yes as answer to all prompts.
Submit bugs and feature requests to http://github.com/samg/timetrap/issues
EOF
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Helpers
format_date, format_date_if_new, format_duration, format_seconds, format_time, format_total, same_day?, selected_entries, sheet_name_from_string
Instance Attribute Details
#args ⇒ Object
Returns the value of attribute args.
4
5
6
|
# File 'lib/timetrap/cli.rb', line 4
def args
@args
end
|
Instance Method Details
#archive ⇒ Object
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/timetrap/cli.rb', line 127
def archive
ee = selected_entries
if ask_user "Archive #{ee.count} entries? "
ee.all.each do |e|
next unless e.end
e.update :sheet => "_#{e.sheet}"
end
else
say "archive aborted!"
end
end
|
#backend ⇒ Object
168
169
170
|
# File 'lib/timetrap/cli.rb', line 168
def backend
exec "sqlite3 #{DB_NAME}"
end
|
#commands ⇒ Object
102
103
104
|
# File 'lib/timetrap/cli.rb', line 102
def commands
Timetrap::CLI::USAGE.scan(/\* \w+/).map{|s| s.gsub(/\* /, '')}
end
|
139
140
141
142
|
# File 'lib/timetrap/cli.rb', line 139
def configure
Config.configure!
say "Config file is at #{Config::PATH.inspect}"
end
|
#display ⇒ Object
Also known as:
format
204
205
206
207
208
209
210
211
212
213
214
215
216
|
# File 'lib/timetrap/cli.rb', line 204
def display
begin
fmt_klass = if args['-f']
Timetrap::Formatters.const_get("#{args['-f'].classify}")
else
Timetrap::Formatters::Text
end
rescue
say "Invalid format specified `#{args['-f']}'"
return
end
say Timetrap.format(fmt_klass, selected_entries.order(:start).all)
end
|
#edit ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/timetrap/cli.rb', line 144
def edit
entry = args['-i'] ? Entry[args['-i']] : Timetrap.active_entry
say "can't find entry" && return unless entry
entry.update :start => args['-s'] if args['-s'] =~ /.+/
entry.update :end => args['-e'] if args['-e'] =~ /.+/
if args['-m'] =~ /.+/
if entry == Timetrap.active_entry
Timetrap.current_sheet = args['-m']
end
entry.update :sheet => args['-m']
end
if unused_args =~ /.+/
note = unused_args
if args['-z']
note = [entry.note, note].join(Config['append_notes_delimiter'])
end
entry.update :note => note
end
end
|
#in ⇒ Object
172
173
174
|
# File 'lib/timetrap/cli.rb', line 172
def in
Timetrap.start unused_args, args['-a']
end
|
#invoke ⇒ Object
95
96
97
98
99
100
|
# File 'lib/timetrap/cli.rb', line 95
def invoke
args['-h'] ? say(USAGE) : invoke_command_if_valid
rescue => e
say e.message
exit 1
end
|
#invoke_command_if_valid ⇒ Object
110
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/timetrap/cli.rb', line 110
def invoke_command_if_valid
command = args.unused.shift
set_global_options
case (valid = commands.select{|name| name =~ %r|^#{command}|}).size
when 0 then say "Invalid command: #{command}"
when 1 then send valid[0]
else
say "Ambiguous command: #{command}" if command
say(USAGE)
end
end
|
#kill ⇒ Object
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
# File 'lib/timetrap/cli.rb', line 180
def kill
if e = Entry[args['-i']]
out = "are you sure you want to delete entry #{e.id}? "
out << "(#{e.note}) " if e.note.to_s =~ /.+/
if ask_user out
e.destroy
say "it's dead"
else
say "will not kill"
end
elsif (sheets = Entry.map{|e| e.sheet }.uniq).include?(sheet = unused_args)
victims = Entry.filter(:sheet => sheet).count
if ask_user "are you sure you want to delete #{victims} entries on sheet #{sheet.inspect}? "
Timetrap.kill_sheet sheet
say "killed #{victims} entries"
else
say "will not kill"
end
else
victim = args['-i'] ? args['-i'].to_s.inspect : sheet.inspect
say "can't find #{victim} to kill", 'sheets:', *sheets
end
end
|
#list ⇒ Object
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
# File 'lib/timetrap/cli.rb', line 226
def list
sheets = Entry.sheets.map do |sheet|
sheet_atts = {:total => 0, :running => 0, :today => 0}
Timetrap::Entry.filter(:sheet => sheet).inject(sheet_atts) do |m, e|
e_end = e.end_or_now
m[:name] ||= sheet
m[:total] += (e_end.to_i - e.start.to_i)
m[:running] += (e_end.to_i - e.start.to_i) unless e.end
m[:today] += (e_end.to_i - e.start.to_i) if same_day?(Time.now, e.start)
m
end
end
if sheets.empty? then say "No sheets found"; return end
width = sheets.sort_by{|h|h[:name].length }.last[:name].length + 4
say " %-#{width}s%-12s%-12s%s" % ["Timesheet", "Running", "Today", "Total Time"]
sheets.each do |sheet|
star = sheet[:name] == Timetrap.current_sheet ? '*' : ' '
say "#{star}%-#{width}s%-12s%-12s%s" % [
sheet[:running],
sheet[:today],
sheet[:total]
].map(&method(:format_seconds)).unshift(sheet[:name])
end
end
|
#out ⇒ Object
176
177
178
|
# File 'lib/timetrap/cli.rb', line 176
def out
Timetrap.stop args['-a']
end
|
#parse(arguments) ⇒ Object
91
92
93
|
# File 'lib/timetrap/cli.rb', line 91
def parse arguments
args.parse arguments
end
|
#running ⇒ Object
261
262
263
264
|
# File 'lib/timetrap/cli.rb', line 261
def running
say "Running Timesheets:"
say Timetrap::Entry.filter(:end => nil).map{|e| " #{e.sheet}: #{e.note}"}.uniq.sort
end
|
#say(*something) ⇒ Object
106
107
108
|
# File 'lib/timetrap/cli.rb', line 106
def say *something
puts *something
end
|
#set_global_options ⇒ Object
currently just sets whether output should be rounded to 15 min intervals
123
124
125
|
# File 'lib/timetrap/cli.rb', line 123
def set_global_options
Timetrap::Entry.round = true if args['-r']
end
|
#switch ⇒ Object
220
221
222
223
224
|
# File 'lib/timetrap/cli.rb', line 220
def switch
sheet = unused_args
if not sheet =~ /.+/ then say "No sheet specified"; return end
say "Switching to sheet " + Timetrap.switch(sheet)
end
|
#week ⇒ Object
266
267
268
269
|
# File 'lib/timetrap/cli.rb', line 266
def week
args['-s'] = Date.today.wday == 1 ? Date.today.to_s : Date.parse(Chronic.parse(%q(last monday)).to_s).to_s
display
end
|