require_relative 'config_loader' # frozen_string_literal: true require 'cache_method' require 'asana' # Pull tasks from asana.com # # Convention: # _raw: Returns tasks objects, including section-tasks # _tasks: Returns task objects # _task_names: Returns an array of strings, no sections included # _by_section: Returns a hash from section name to array module Checkoff # Work with projects in Asana class Projects MINUTE = 60 HOUR = MINUTE * 60 DAY = 24 * HOUR REALLY_LONG_CACHE_TIME = HOUR * 1 LONG_CACHE_TIME = MINUTE * 15 SHORT_CACHE_TIME = MINUTE * 5 # XXX: Move low-level functions private def initialize(config: Checkoff::ConfigLoader.load(:asana), asana_client: Asana::Client) @config = config @asana_client = asana_client end def client @client ||= @asana_client.new do |c| c.authentication :access_token, @config[:personal_access_token] end end def projects client.projects end cache_method :projects, LONG_CACHE_TIME def add_task(name, workspace_id: default_workspace_id, assignee_id: default_assignee_id) Asana::Resources::Task.create(client, assignee: assignee_id, workspace: workspace_id, name: name) end def default_workspace_id @config[:default_workspace_id] end def default_assignee_id @config[:default_assignee_id] end def user_by_name(name, workspace_id: raise) client.users.find_all(workspace: workspace_id).find do |user| print(user) user.name == name end || raise("Could not find user #{email}") end def workspace_by_name(workspace_name) client.workspaces.find_all.find do |workspace| workspace.name == workspace_name end || raise("Could not find workspace #{workspace_name}") end def projects_by_workspace_name(workspace_name) workspace = workspace_by_name(workspace_name) raise "Could not find workspace named #{workspace_name}" unless workspace projects.find_by_workspace(workspace: workspace.id) end def my_tasks(workspace_name) my_tasks = @config[:my_tasks] id = @config[:my_tasks][workspace_name] unless my_tasks.nil? if my_tasks.nil? || id.nil? raise "Please define [:my_tasks][#{workspace_name}] in config file" end projects.find_by_id(id) end def project(workspace_name, project_name) if project_name.is_a?(Symbol) && project_name.to_s.start_with?('my_tasks') my_tasks(workspace_name) else projects = projects_by_workspace_name(workspace_name) projects.find do |project| project.name == project_name end end end cache_method :project, LONG_CACHE_TIME def active_tasks(tasks) tasks.select { |task| task.completed_at.nil? } end def task_options { options: { fields: %w(name assignee_status completed_at due_at due_on), }, } end def tasks_from_project(project) project.tasks(task_options).to_a end cache_method :tasks_from_project, LONG_CACHE_TIME end end