Class: Checkoff::Projects

Inherits:
Object
  • Object
show all
Extended by:
CacheMethod::ClassMethods
Defined in:
lib/checkoff/projects.rb

Overview

Work with projects in Asana

Constant Summary collapse

MINUTE =
60
HOUR =
MINUTE * 60
DAY =
24 * HOUR
REALLY_LONG_CACHE_TIME =
HOUR * 1
LONG_CACHE_TIME =
MINUTE * 15
MEDIUM_CACHE_TIME =
MINUTE * 5
SHORT_CACHE_TIME =
MINUTE

Instance Method Summary collapse

Constructor Details

#initialize(config: Checkoff::Internal::ConfigLoader.load(:asana), client: Checkoff::Clients.new(config: config).client, workspaces: Checkoff::Workspaces.new(config: config, client: client), project_hashes: Checkoff::Internal::ProjectHashes.new, project_timing: Checkoff::Internal::ProjectTiming.new(client: client), timing: Checkoff::Timing.new) ⇒ Projects

Returns a new instance of Projects.

Parameters:

  • config (Hash<Symbol, Object>) (defaults to: Checkoff::Internal::ConfigLoader.load(:asana))
  • client (Asana::Client) (defaults to: Checkoff::Clients.new(config: config).client)
  • workspaces (Checkoff::Workspaces) (defaults to: Checkoff::Workspaces.new(config: config, client: client))
  • project_hashes (Checkoff::Internal::ProjectHashes) (defaults to: Checkoff::Internal::ProjectHashes.new)
  • project_timing (Checkoff::Internal::ProjectTiming) (defaults to: Checkoff::Internal::ProjectTiming.new(client: client))
  • timing (Checkoff::Timing) (defaults to: Checkoff::Timing.new)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/checkoff/projects.rb', line 39

def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
               client: Checkoff::Clients.new(config: config).client,
               workspaces: Checkoff::Workspaces.new(config: config,
                                                    client: client),
               project_hashes: Checkoff::Internal::ProjectHashes.new,
               project_timing: Checkoff::Internal::ProjectTiming.new(client: client),
               timing: Checkoff::Timing.new)
  @config = config
  @workspaces = workspaces
  @client = client
  @project_hashes = project_hashes
  @project_timing = project_timing
  @timing = timing
end

Instance Method Details

#active_tasks(tasks) ⇒ Enumerable<Asana::Resources::Task>

find uncompleted tasks in a list

Parameters:

  • tasks (Enumerable<Asana::Resources::Task>)

Returns:

  • (Enumerable<Asana::Resources::Task>)


111
112
113
# File 'lib/checkoff/projects.rb', line 111

def active_tasks(tasks)
  tasks.select { |task| task.completed_at.nil? }
end

#in_period?(project, field_name, period) ⇒ Boolean

Parameters:

  • project (Asana::Resources::Project)
  • field_name (Symbol, Array)
  • period (Symbol<:now_or_before,:this_week>, Array)

    See Checkoff::Timing#in_period?

Returns:

  • (Boolean)


186
187
188
189
190
191
# File 'lib/checkoff/projects.rb', line 186

def in_period?(project, field_name, period)
  # @type [Date,Time,nil]
  project_date = project_timing.date_or_time_field_by_name(project, field_name)

  timing.in_period?(project_date, period)
end

#project(workspace_name, project_name, extra_fields: []) ⇒ Asana::Resources::Project?

pulls an Asana API project class given a name

Parameters:

  • workspace_name (String)
  • project_name (String, Symbol<:my_tasks>)
  • extra_fields (Array<String>) (defaults to: [])

Returns:

  • (Asana::Resources::Project, nil)


73
74
75
76
77
78
79
80
81
82
83
# File 'lib/checkoff/projects.rb', line 73

def project(workspace_name, project_name, extra_fields: [])
  if project_name.is_a?(Symbol) && project_name.to_s.start_with?('my_tasks')
    my_tasks(workspace_name)
  else
    # @type [Enumerable<Asana::Resources::Project>]
    ps = projects_by_workspace_name(workspace_name, extra_fields: extra_fields)
    ps.find do |project|
      project.name == project_name
    end
  end
end

#project_by_gid(gid, extra_fields: []) ⇒ Asana::Resources::Project

Parameters:

  • gid (String)
  • extra_fields (Array<String>) (defaults to: [])

Returns:

  • (Asana::Resources::Project)


103
104
105
# File 'lib/checkoff/projects.rb', line 103

def project_by_gid(gid, extra_fields: [])
  projects.find_by_id(gid, options: { fields: %w[name] + extra_fields })
end

#project_or_raise(workspace_name, project_name, extra_fields: []) ⇒ Asana::Resources::Project

Parameters:

  • workspace_name (String)
  • project_name (String, Symbol<:my_tasks>)
  • extra_fields (Array<String>) (defaults to: [])

Returns:

  • (Asana::Resources::Project)


91
92
93
94
95
96
# File 'lib/checkoff/projects.rb', line 91

def project_or_raise(workspace_name, project_name, extra_fields: [])
  p = project(workspace_name, project_name, extra_fields: extra_fields)
  raise "Could not find project #{project_name.inspect} under workspace #{workspace_name}." if p.nil?

  p
end

#project_ready?(project, period: :now_or_before) ⇒ Boolean

Indicates a project is ready for a person to work on it. This is subtly different than what is used by Asana to mark a date as red/green!

A project is ready if there is no start date, or if the start date is today or in the past.

Parameters:

  • project (Asana::Resources::Project)
  • period (Symbol<:now_or_before,:this_week>) (defaults to: :now_or_before)

Returns:

  • (Boolean)


179
180
181
# File 'lib/checkoff/projects.rb', line 179

def project_ready?(project, period: :now_or_before)
  in_period?(project, :ready, period)
end

#project_to_h(project_obj, project: :not_specified) ⇒ Hash

Parameters:

  • project_obj (Asana::Resources::Project)
  • project (String, Symbol<:not_specified, :my_tasks>) (defaults to: :not_specified)

Returns:

  • (Hash)


166
167
168
# File 'lib/checkoff/projects.rb', line 166

def project_to_h(project_obj, project: :not_specified)
  project_hashes.project_to_h(project_obj, project: project)
end

#projects_by_workspace_name(workspace_name, extra_fields: []) ⇒ Enumerable<Asana::Resources::Project>

Parameters:

  • workspace_name (String)
  • extra_fields (Array<String>) (defaults to: [])

Returns:

  • (Enumerable<Asana::Resources::Project>)


152
153
154
155
156
157
158
159
# File 'lib/checkoff/projects.rb', line 152

def projects_by_workspace_name(workspace_name, extra_fields: [])
  workspace = @workspaces.workspace_or_raise(workspace_name)
  options = { fields: %w[name] + extra_fields }
  # 15 minute cache resulted in 'Your pagination token has
  # expired', so let's cache this a super long time and force
  # evaluation
  projects.find_by_workspace(workspace: workspace.gid, per_page: 100, options: options).to_a
end

#task_optionsHash<Symbol, Object>

Default options used in Asana API to pull tasks

Returns:

  • (Hash<Symbol, Object>)


56
57
58
59
60
61
62
63
64
65
# File 'lib/checkoff/projects.rb', line 56

def task_options
  {
    per_page: 100,
    options: {
      fields: %w[name completed_at start_at start_on due_at due_on tags
                 memberships.project.gid memberships.project.name
                 memberships.section.name dependencies],
    },
  }
end

#tasks_from_project(project, only_uncompleted: true, extra_fields: []) ⇒ Enumerable<Asana::Resources::Task>

Pull task objects from a named project

Parameters:

  • project (Asana::Resources::Project)
  • only_uncompleted (Boolean) (defaults to: true)
  • extra_fields (Array<String>) (defaults to: [])

Returns:

  • (Enumerable<Asana::Resources::Task>)


122
123
124
125
126
127
128
# File 'lib/checkoff/projects.rb', line 122

def tasks_from_project(project,
                       only_uncompleted: true,
                       extra_fields: [])
  tasks_from_project_gid(project.gid,
                         only_uncompleted: only_uncompleted,
                         extra_fields: extra_fields)
end

#tasks_from_project_gid(project_gid, only_uncompleted: true, extra_fields: []) ⇒ Enumerable<Asana::Resources::Task>

Pull task objects from a project identified by a gid

Parameters:

  • project_gid (String)
  • only_uncompleted (Boolean) (defaults to: true)
  • extra_fields (Array<String>) (defaults to: [])

Returns:

  • (Enumerable<Asana::Resources::Task>)


138
139
140
141
142
143
144
145
146
# File 'lib/checkoff/projects.rb', line 138

def tasks_from_project_gid(project_gid,
                           only_uncompleted: true,
                           extra_fields: [])
  options = task_options
  options[:completed_since] = '9999-12-01' if only_uncompleted
  options[:project] = project_gid
  options[:options][:fields] += extra_fields
  client.tasks.find_all(**options)
end