Class: Timet::Application

Inherits:
Thor
  • Object
show all
Includes:
ApplicationHelper, TimeHelper, ValidationEditHelper
Defined in:
lib/timet/application.rb

Overview

Application class that defines CLI commands for time tracking:

  • start: Start time tracking with optional notes

  • stop: Stop time tracking

  • resume: Resume the last task

  • summary: Display a summary of tracked time and export to CSV

  • edit: Edit a task

  • delete: Delete a task

  • cancel: Cancel active time tracking

Constant Summary collapse

FIELD_INDEX =
{
  'notes' => 4,
  'tag' => 3,
  'start' => 1,
  'end' => 2
}.freeze
VALID_STATUSES_FOR_INSERTION =
%i[no_items complete].freeze
VALID_ARGUMENTS =
%w[
  cancel
  delete
  edit
  help
  resume
  start
  stop
  summary
  sync
  version
].freeze
BUCKET =
'timet'

Constants included from ValidationEditHelper

ValidationEditHelper::TIME_FIELDS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TimeHelper

append_tag_to_hour_blocks, beginning_of_day, calculate_block_end_time_and_seconds, calculate_duration, calculate_end_time, count_seconds_per_hour_block, create_new_datetime, current_timestamp, date_to_timestamp, extract_date, format_time, format_time_string, parse_time_components, timestamp_to_date, timestamp_to_time, update_time_field, valid_time?

Methods included from ApplicationHelper

#build_options, #delete_item_and_print_message, #display_and_export_report, #display_item, #export_report, #field_value, #play_sound_and_notify, #prompt_for_new_value, #resume_complete_task, #run_linux_session, #run_mac_session, #select_field_to_edit, #show_message

Methods included from ValidationEditHelper

#check_collision_with_next_item, #check_collision_with_previous_item, #validate_and_update, #validate_time, #validate_time_collisions

Methods included from TimeValidationHelper

#adjust_end_datetime, #create_new_datetime, #determine_base_date_time, #parse_time_string, #validate_end_time, #validate_future_date, #validate_start_time

Constructor Details

#initialize(*args) ⇒ Application

Returns a new instance of Application.



53
54
55
56
57
# File 'lib/timet/application.rb', line 53

def initialize(*args)
  super
  config = args[2] || {} # Third argument is the config hash
  initialize_database(config)
end

Class Method Details

.exit_on_failure?Boolean

Note:

This method is typically used in command-line applications to control the behavior when a command fails.

Note:

Returning ‘true` means that the application will exit immediately if a command fails, which is useful for

Determines whether the application should exit when a command fails.

ensuring that errors are handled gracefully.

Examples:

Check if the application should exit on failure

MyClass.exit_on_failure? # => true

Returns:

  • (Boolean)

    Returns ‘true`, indicating that the application should exit when a command fails.



337
338
339
# File 'lib/timet/application.rb', line 337

def self.exit_on_failure?
  true
end

Instance Method Details

#cancelvoid

Note:

The method fetches the ID of the last tracking item using ‘@db.fetch_last_id`.

Note:

It checks if the last item is in progress by comparing ‘@db.item_status` with `:complete`.

Note:

If the last item is in progress, it deletes the item and prints a confirmation message using

Note:

If there is no active time tracking, it prints a message indicating that there is no active time tracking.

This method returns an undefined value.

Cancels the active time tracking session by deleting the last tracking item.

item and displaying a confirmation message.

‘delete_item_and_print_message(id, “Canceled active time tracking #id”)`.

Examples:

Cancel the active time tracking session

cancel


320
321
322
323
324
325
# File 'lib/timet/application.rb', line 320

def cancel
  id = @db.fetch_last_id
  return puts 'There is no active time tracking' if @db.item_status == :complete

  delete_item_and_print_message(id, "Canceled active time tracking #{id}")
end

#delete(id) ⇒ void

Note:

The method first attempts to find the tracking item by its ID using ‘@db.find_item(id)`.

Note:

If the item is found, it displays the item details using ‘TimeReport.new(@db).show_row(item)`.

Note:

The method then prompts the user for confirmation using ‘TTY::Prompt.new.yes?(’Are you sure you want

Note:

If the user confirms, the method deletes the item and prints a confirmation message using

This method returns an undefined value.

Deletes a specific tracking item by its ID after confirming with the user.

and displaying a confirmation message.

to delete this entry?‘)`. `delete_item_and_print_message(id, “Deleted #id”)`.

Examples:

Delete a tracking item with ID 1

delete(1)

Parameters:

  • id (Integer)

    The ID of the tracking item to be deleted.



296
297
298
299
300
301
302
303
304
# File 'lib/timet/application.rb', line 296

def delete(id)
  item = @db.find_item(id)
  return puts "No tracked time found for id: #{id}" unless item

  TimeReport.new(@db).show_row(item)
  return unless TTY::Prompt.new.yes?('Are you sure you want to delete this entry?')

  delete_item_and_print_message(id, "Deleted #{id}")
end

#edit(id = nil, field = nil, new_value = nil) ⇒ void

Note:

The method first attempts to find the tracking item by its ID using ‘@db.find_item(id)`.

Note:

If the item is found, it displays the current item details using ‘display_item(item)`.

Note:

If the field or new value is not provided, the user is prompted to select a field to edit and enter

Note:

The method then validates and updates the item using ‘validate_and_update(item, field, new_value)`.

Note:

Finally, it displays the updated item details using ‘display_item(updated_item)`.

This method returns an undefined value.

Edits a specific tracking item by its ID, allowing the user to modify fields such as notes, tag, start time, or end time.

If not provided, the user will be prompted to select a field. prompted to enter a new value.

and displaying the updated item.

a new value.

Examples:

Edit the notes of a tracking item with ID 1

edit(1, 'notes', 'Updated notes')

Edit a tracking item with ID 2, prompting for the field and new value

edit(2)

Parameters:

  • id (Integer) (defaults to: nil)

    The ID of the tracking item to be edited.

  • field (String, nil) (defaults to: nil)

    The field to be edited. Possible values include ‘notes’, ‘tag’, ‘start’, or ‘end’.

  • new_value (String, nil) (defaults to: nil)

    The new value to be set for the specified field. If not provided, the user will be



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/timet/application.rb', line 263

def edit(id = nil, field = nil, new_value = nil)
  id = @db.fetch_last_id if id.nil?
  item = @db.find_item(id)
  return puts "No tracked time found for id: #{id}" unless item

  display_item(item)
  if field.nil? || new_value.nil?
    field = select_field_to_edit
    new_value = prompt_for_new_value(item, field)
  end

  updated_item = validate_and_update(item, field, new_value)
  @db.update_item(id, field, updated_item[FIELD_INDEX[field]])
  display_item(updated_item)
end

#resume(id = nil) ⇒ void

Note:

The method checks the status of the last tracking item using ‘@db.item_status`.

Note:

If the last item is in progress, it prints a message indicating that a task is currently being tracked.

Note:

If the last item is complete, it fetches the last item using ‘@db.find_item` or `@db.last_item`,

This method returns an undefined value.

Resumes the last tracking session if it was completed.

or providing feedback.

retrieves the tag and notes, and calls the ‘start` method to resume the tracking session.

Examples:

Resume the last tracking session

resume

Resume a specific task by ID

resume(123)

Parameters:

  • id (Integer, nil) (defaults to: nil)

    The ID of the tracking item to resume. If nil, the last item is used.

See Also:



193
194
195
196
197
198
199
200
# File 'lib/timet/application.rb', line 193

def resume(id = nil)
  case @db.item_status(id)
  when :in_progress
    puts 'A task is currently being tracked.'
  when :complete
    resume_complete_task(id)
  end
end

#start(tag, notes = nil, pomodoro = nil) ⇒ void

Note:

The method uses ‘TimeHelper.current_timestamp` to get the current timestamp for the start time.

Note:

The method calls ‘play_sound_and_notify` if a Pomodoro time is provided.

Note:

The method calls ‘summary` to generate a summary after inserting the tracking item.

This method returns an undefined value.

Starts a new tracking session with the given tag and optional notes.

This method initializes a new tracking session by inserting a new item into the database with the provided tag and optional notes. If a Pomodoro time is specified, it will also trigger a sound and notification after the specified time has elapsed.

defaults to the value in ‘options`. `options`.

playing a sound, sending a notification, and generating a summary.

Examples:

Start a tracking session with a tag and notes

start('work', 'Starting work on project X', 25)

Start a tracking session with only a tag

start('break')

Parameters:

  • tag (String)

    The tag associated with the tracking session. This is a required parameter.

  • notes (String, nil) (defaults to: nil)

    Optional notes to be associated with the tracking session. If not provided, it

  • pomodoro (Numeric, nil) (defaults to: nil)

    Optional Pomodoro time in minutes. If not provided, it defaults to the value in



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/timet/application.rb', line 133

def start(tag, notes = nil, pomodoro = nil)
  start_time = TimeHelper.current_timestamp
  notes = options[:notes] || notes
  pomodoro = (options[:pomodoro] || pomodoro).to_i

  return puts 'A task is currently being tracked.' unless VALID_STATUSES_FOR_INSERTION.include?(@db.item_status)

  @db.insert_item(start_time, tag, notes, pomodoro, start_time, start_time)
  DiscordNotifier.pomodoro_started(pomodoro) if pomodoro.positive? # Notify that a Pomodoro session has started
  play_sound_and_notify(pomodoro * 60, tag) if pomodoro.positive?
  summary
end

#stopvoid

Note:

The method checks if the last tracking item is in progress by calling ‘@db.item_status`.

Note:

If the last item is in progress, it fetches the last item’s ID using ‘@db.fetch_last_id` and updates it

Note:

The method always generates a summary after stopping the tracking session.

This method returns an undefined value.

Stops the current tracking session if there is one in progress. After stopping the tracking session, it displays a summary of the tracked time.

and generating a summary.

with the current timestamp.

Examples:

Stop the current tracking session

stop


160
161
162
163
164
165
166
167
# File 'lib/timet/application.rb', line 160

def stop
  return unless @db.item_status == :in_progress

  last_id = @db.fetch_last_id
  @db.find_item(last_id) # Fetch the item to get pomodoro duration
  @db.update_item(last_id, 'end', TimeHelper.current_timestamp)
  summary
end

#summary(time_scope = nil, tag = nil) ⇒ void

This method returns an undefined value.

Generates a summary of tracking items based on the provided time_scope and tag, and optionally exports the summary to a CSV file and/or an iCalendar file.

and exporting the report.

Parameters:

  • time_scope (String, nil) (defaults to: nil)

    The filter to apply when fetching items. Possible values include ‘today’, ‘yesterday’, ‘week’, ‘month’, or a date range in the format ‘YYYY-MM-DD..YYYY-MM-DD’.

  • tag (String, nil) (defaults to: nil)

    The tag to filter the items by.



224
225
226
227
228
229
230
231
# File 'lib/timet/application.rb', line 224

def summary(time_scope = nil, tag = nil)
  options = build_options(time_scope, tag)
  report = TimeReport.new(@db, options)
  display_and_export_report(report, options)
  return unless options[:report]

  report.print_tag_explanation_report
end

#syncObject



354
355
356
357
358
# File 'lib/timet/application.rb', line 354

def sync
  puts 'Syncing database with remote storage...'
  puts 'Sync method called'
  DatabaseSyncHelper.sync(@db, BUCKET)
end

#versionObject



349
350
351
# File 'lib/timet/application.rb', line 349

def version
  puts Timet::VERSION
end