class TogglCLI

Constants

FILTERS
SHOW_REPORTS_COLUMNS

Public Instance Methods

batch() click to toggle source
# File lib/toggl_cli.rb, line 25
def batch
  # TEMP
  # source_project = select_project("Select the source project")
  # source_task = select_task("Select the source task", source_project["id"])
  source_project = { "name" => "technical (fake)", "id" => 9800254 }
  source_task = { "name" => "No task", "id" => nil }
  # END TEMP

  reports = find_reports(source_project["id"], source_task["id"])
  show_reports_info(reports)
  reports = filter_reports(reports)

  unless no?("Move these reports to a new project / task (enter 'n' or 'no' to cancel)")
    target_project = select_project("Select the target project")
    target_task = select_task("Select the target task", target_project["id"])

    say(
      "Will move #{reports.count} reports, " \
      "from #{source_project['name']} > #{source_task['name']} " \
      "to #{target_project['name']} > #{target_task['name']}"
    )
    if yes?("Are you sure? (enter 'y' or 'yes' to continue)")
      say("MOVING!!!")
    end
  end
  TogglCache::Data::ReportRepository.new.create_or_update(report)
end

Private Instance Methods

build_bar(msg, count) click to toggle source
# File lib/toggl_cli.rb, line 178
def build_bar(msg, count)
  TTY::ProgressBar.new("#{msg} [:bar]", total: count)
end
build_spinner(title) click to toggle source
# File lib/toggl_cli.rb, line 174
def build_spinner(title)
  TTY::Spinner.new("#{title} [:spinner]")
end
client() click to toggle source
# File lib/toggl_cli.rb, line 170
def client
  @client ||= TogglAPI::Client.new
end
filter_reports(reports) click to toggle source
# File lib/toggl_cli.rb, line 55
def filter_reports(reports)
  begin
    selected_filter = ask("Add filter?", limited_to: FILTERS)
    reports = (
      case selected_filter
      when "no" then reports
      when "description" then propose_description_regexp_filter(reports)
      when "user" then propose_user_filter(reports)
      else raise "Unexpected filter `#{selected_filter}`"
      end
    )
    show_reports_info(reports)
  end while(selected_filter != "no")
  reports
end
find_reports(project_id, task_id) click to toggle source
# File lib/toggl_cli.rb, line 113
def find_reports(project_id, task_id)
  reports = TogglCache::Data::ReportRepository.new
  with_spinner("Fetching matching reports...") do
    reports.where(project_id: project_id&.to_i, task_id: task_id&.to_i)
  end
end
page(text) click to toggle source
# File lib/toggl_cli.rb, line 190
def page(text)
  pager = TTY::Pager::BasicPager.new
  pager.page(text)
end
project_names() click to toggle source
# File lib/toggl_cli.rb, line 166
def project_names
  projects.map { |p| p["name"] }
end
project_tasks(project_id) click to toggle source
# File lib/toggl_cli.rb, line 157
def project_tasks(project_id)
  tasks = with_spinner("Fetching tasks...") do
    client.get_project_tasks(project_id: project_id)
  end
  tasks.map do |task|
    { "id" => task["id"], "name" => task["name"] }
  end
end
projects() click to toggle source
# File lib/toggl_cli.rb, line 149
def projects
  @projects ||= (
    with_spinner("Fetching projects...") do
      client.get_workspace_projects(active: "both")
    end
  )
end
propose_description_regexp_filter(reports) click to toggle source
# File lib/toggl_cli.rb, line 71
def propose_description_regexp_filter(reports)
  show_unique_descriptions(reports)
  if yes?("Add regexp filter? (enter 'y' or 'yes' to continue)")
    regexp = eval(ask("Enter regexp (e.g. /string/i - will go through `eval`):"))
    filtered = reports.select { |r| r[:description] =~ regexp }
    show_unique_descriptions(filtered)
    return filtered unless no?("Keep filter? (enter 'n' or 'no' to discard the filter)")
  end
  reports
end
propose_user_filter(reports) click to toggle source
# File lib/toggl_cli.rb, line 82
def propose_user_filter(reports)
  selected_user = select_in_list(reports.map { |r| r[:user] }.uniq, "Select user")
  filtered = reports.select { |r| r[:user] == selected_user }
  show_reports_info(filtered)
  return filtered unless no?("Keep filter? (enter 'n' or 'no' to discard the filter)")
  reports
end
select_in_list(items, msg) click to toggle source
# File lib/toggl_cli.rb, line 120
def select_in_list(items, msg)
  items.each.with_index { |item, i| say("  #{i}. #{item}") }
  begin
    index = ask("#{msg} (0-#{items.count - 1})").to_i
  end while(index < 0 || index > items.count - 1)
  items[index]
end
select_project(msg) click to toggle source
# File lib/toggl_cli.rb, line 128
def select_project(msg)
  say("Projects:")
  project_name = select_in_list(project_names, msg)
  project = projects.find { |p| p["name"] == project_name }
  say("Selected project `#{project["name"]}`")
  project
end
select_task(msg, project_id) click to toggle source
# File lib/toggl_cli.rb, line 136
def select_task(msg, project_id)
  source_project_tasks = project_tasks(project_id)
  return { "id" => nil, "name" => "No task" } if source_project_tasks.empty?
  say("Tasks for selected project:")
  source_project_tasks.each.with_index do |task, i|
    say("  #{i}. #{task['name']}")
  end
  begin
    source_task_index = ask("#{msg} (0-#{source_project_tasks.count - 1})").to_i
  end while(source_task_index < 0 || source_task_index > source_project_tasks.count - 1)
  source_task = source_project_tasks[source_task_index]
end
show_reports(reports) click to toggle source
# File lib/toggl_cli.rb, line 103
def show_reports(reports)
  report_lines = reports.map do |r|
    report_columns = SHOW_REPORTS_COLUMNS.map do |c|
      r[c.to_sym]
    end
    report_columns.join(" | ")
  end
  page(report_lines.join("\n") << "\n")
end
show_reports_info(reports) click to toggle source
# File lib/toggl_cli.rb, line 98
def show_reports_info(reports)
  say("#{reports.count} matching reports.")
  show_reports(reports) if yes?("Show reports? (enter 'y' or 'yes' to show)")
end
show_unique_descriptions(reports) click to toggle source
# File lib/toggl_cli.rb, line 90
def show_unique_descriptions(reports)
  unique_descriptions = reports.map { |r| r[:description] }.uniq
  say("Found #{unique_descriptions.count} unique descriptions.")
  if yes?("Show unique descriptions? (enter 'y' or 'yes' to show)")
    page(unique_descriptions.join("\n") << "\n")
  end
end
with_spinner(msg) { || ... } click to toggle source
# File lib/toggl_cli.rb, line 182
def with_spinner(msg)
  spinner = build_spinner(msg)
  result = nil
  yield
  spinner.run("Done!") { result = yield }
  result
end