class TaskReport::Report

Constants

MultipleOngoingTasks
TaskAlreadyOngoing
TaskAlreadyTracked
TaskDNE

Attributes

gist_id[R]

Public Class Methods

create(new_task_description:) click to toggle source
# File lib/task_report/report.rb, line 19
def create(new_task_description:)
  Report.new(
    description: gist_description,
    json_file_name: json_file_name
  )
end
create_from_gist(gist) click to toggle source
# File lib/task_report/report.rb, line 26
def create_from_gist(gist)
  description = gist['description'] || gist_description
  raw_url = gist['files'][json_file_name(description)]['raw_url']

  Report.new(
    description: description,
    json_file_name: json_file_name,
    gist_id: gist['id'],
    gist_html_url: gist['html_url'],
    existing_json_content: Gist.file_content(raw_url)
  )
end
gist_description(time = Time.now) click to toggle source
# File lib/task_report/report.rb, line 11
def gist_description(time = Time.now)
  "#{User.name}_report_#{time.strftime('%Y-%m-%d')}"
end
json_file_name(description = nil) click to toggle source
# File lib/task_report/report.rb, line 15
def json_file_name(description = nil)
  "#{description || gist_description}.json"
end
new(description:, json_file_name:, gist_id: nil, gist_html_url: nil, existing_json_content: {}) click to toggle source
# File lib/task_report/report.rb, line 186
def initialize(description:, json_file_name:, gist_id: nil, gist_html_url: nil, existing_json_content: {})
  @description = description
  @json_file_name = json_file_name
  @gist_id = gist_id
  @gist_html_url = gist_html_url

  @date = Time.parse(
    existing_json_content.fetch('date', Time.now.strftime('%Y-%m-%d %z'))
  )

  @tasks =
    existing_json_content.fetch('tasks', []).map do |hash|
      Task.from_existing_tasks(hash)
    end
end

Public Instance Methods

add_note(task_id, note) click to toggle source
# File lib/task_report/report.rb, line 155
def add_note(task_id, note)
  task = find_task_by_id(task_id)
  raise TaskDNE if task.nil?

  task.add_note(note)
  puts "Note added to #{task.to_s}"
end
continue(task_id) click to toggle source
# File lib/task_report/report.rb, line 54
def continue(task_id)
  ensure_no_tasks_ongoing!

  task =
    if task_id.nil?
      find_last_task_to_be_worked_on
    else
      find_task_by_id(task_id) || find_task_by_description(task_id)
    end

  task.continue
end
delete(task_id) click to toggle source
# File lib/task_report/report.rb, line 67
def delete(task_id)
  task = find_task_by_id(task_id) || find_task_by_description(task_id)
  raise TaskDNE if task.nil?

  puts "Deleting #{task.to_s}."
  @tasks.delete_if { |t| t.id == task.id }
end
delete_all() click to toggle source
# File lib/task_report/report.rb, line 75
def delete_all
  puts "Deleting all tasks for today."
  @tasks = []
end
gist_summary() click to toggle source
# File lib/task_report/report.rb, line 127
def gist_summary
  if @tasks.empty?
    puts 'There are no tasks reported for today.'
    return
  end

  puts 'Creating a gist summary.'

  Gist.edit(@gist_id,
    description: @description, # do we actually need this? Seems odd...
    files: {
      'summary.md' => {
        content: gist_summary_content
      }
    }
  )

  puts "#{@gist_html_url}#file-summary-md"
end
gist_summary_content() click to toggle source
# File lib/task_report/report.rb, line 167
def gist_summary_content
  lines = ["## #{User.name} Task Report #{@date.strftime('%Y-%m-%d')}", '']

  @tasks.each do |task|
    lines << "- '#{task.description}'"
    lines << "  - #{task.duration.to_s}"

    task.notes.each do |note|
      lines << "  - #{note}"
    end
  end

  lines << ''
  lines << "#### Total time tracked: #{total_duration.to_s}"

  lines.join("\n")
end
print_current_task() click to toggle source
print_summary() click to toggle source
print_tasks() click to toggle source
save_to_gist!() click to toggle source
# File lib/task_report/report.rb, line 147
def save_to_gist!
  if @gist_id
    edit_existing_data_gist!
  else
    save_new_data_gist!
  end
end
start_task(new_task_description) click to toggle source
# File lib/task_report/report.rb, line 40
def start_task(new_task_description)
  if @tasks.any? { |t| t.description == new_task_description }
    raise TaskAlreadyTracked
  end

  task = Task.new(description: new_task_description)
  puts "Starting #{task.to_s}."
  @tasks << task
end
stop_all_tasks() click to toggle source
# File lib/task_report/report.rb, line 50
def stop_all_tasks
  @tasks.each(&:stop)
end
total() click to toggle source
# File lib/task_report/report.rb, line 163
def total
  puts total_duration.to_s
end

Private Instance Methods

edit_existing_data_gist!() click to toggle source
# File lib/task_report/report.rb, line 227
def edit_existing_data_gist!
  puts "Saving to today's report gist."

  Gist.edit(@gist_id,
    description: @description, # do we actually need this? Seems odd...
    files: {
      @json_file_name => {
        content: task_json
      }
    }
  )
end
ensure_no_tasks_ongoing!() click to toggle source
# File lib/task_report/report.rb, line 254
def ensure_no_tasks_ongoing!
  ongoing_task = @tasks.find(&:ongoing?)
  raise TaskAlreadyOngoing, ongoing_task if ongoing_task
end
ensure_only_one_ongoing_task!() click to toggle source
# File lib/task_report/report.rb, line 259
def ensure_only_one_ongoing_task!
  raise MultipleOngoingTasks if @tasks.count(&:ongoing?) > 1
end
find_last_task_to_be_worked_on() click to toggle source
# File lib/task_report/report.rb, line 248
def find_last_task_to_be_worked_on
  @tasks.inject(@tasks.first) do |result, task|
    task.last_start_time > result.last_start_time ? task : result
  end
end
find_task_by_description(task_description) click to toggle source
# File lib/task_report/report.rb, line 244
def find_task_by_description(task_description)
  @tasks.find { |t| t.description == task_description }
end
find_task_by_id(task_id) click to toggle source
# File lib/task_report/report.rb, line 240
def find_task_by_id(task_id)
  @tasks.find { |t| t.id == task_id }
end
save_new_data_gist!() click to toggle source
# File lib/task_report/report.rb, line 213
def save_new_data_gist!
  puts "Starting a new report gist for the day."

  Gist.create(
    public: false,
    description: @description,
    files: {
      @json_file_name => {
        content: task_json
      }
    }
  )
end
task_json() click to toggle source
# File lib/task_report/report.rb, line 209
def task_json
  JSON.pretty_generate(to_h)
end
to_h() click to toggle source
# File lib/task_report/report.rb, line 202
def to_h
  {
    date: @date.strftime('%Y-%m-%d %z'),
    tasks: @tasks.map(&:to_h)
  }
end
total_duration() click to toggle source
# File lib/task_report/report.rb, line 263
def total_duration
  total_time_in_seconds =
    @tasks.inject(0) do |sum, task|
      sum + task.total_time_in_seconds
    end

  Duration.new(total_time_in_seconds)
end