Class: Checkoff::Projects

Inherits:
Object
  • Object
show all
Extended by:
CacheMethod::ClassMethods
Includes:
Logging
Defined in:
lib/checkoff/projects.rb,
sig/checkoff.rbs

Overview

Work with projects in Asana

Constant Summary collapse

MINUTE =

Returns:

  • (Object)
60
HOUR =

Returns:

  • (Object)
MINUTE * 60
DAY =

Returns:

  • (Object)
24 * HOUR
REALLY_LONG_CACHE_TIME =

Returns:

  • (Object)
MINUTE * 30
LONG_CACHE_TIME =

Returns:

  • (Object)
MINUTE * 15
MEDIUM_CACHE_TIME =

Returns:

  • (Object)
MINUTE * 5
SHORT_CACHE_TIME =

Returns:

  • (Object)
MINUTE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

sord warn - Asana::Client wasn't able to be resolved to a constant in this project @param config

@param client

@param workspaces

@param project_hashes

@param project_timing

@param timing



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/checkoff/projects.rb', line 42

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

Instance Attribute Details

#clientAsana::Client (readonly)

sord warn - Asana::Client wasn't able to be resolved to a constant in this project

Returns:

  • (Asana::Client)


250
251
252
# File 'lib/checkoff/projects.rb', line 250

def client
  @client
end

#project_hashesCheckoff::Internal::ProjectHashes (readonly)



247
248
249
# File 'lib/checkoff/projects.rb', line 247

def project_hashes
  @project_hashes
end

#project_timingCheckoff::Internal::ProjectTiming (readonly)



244
245
246
# File 'lib/checkoff/projects.rb', line 244

def project_timing
  @project_timing
end

#timingCheckoff::Timing (readonly)

Returns:



241
242
243
# File 'lib/checkoff/projects.rb', line 241

def timing
  @timing
end

Instance Method Details

#active_tasks(tasks) ⇒ ::Enumerable[Asana::Resources::Task]

sord warn - Asana::Resources::Task wasn't able to be resolved to a constant in this project sord warn - Asana::Resources::Task wasn't able to be resolved to a constant in this project find uncompleted tasks in a list

@param tasks

Parameters:

  • tasks (::Enumerable[Asana::Resources::Task])

Returns:

  • (::Enumerable[Asana::Resources::Task])


148
149
150
# File 'lib/checkoff/projects.rb', line 148

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

#as_cache_keyHash

Returns:

  • (Hash)


232
233
234
# File 'lib/checkoff/projects.rb', line 232

def as_cache_key
  {}
end

#debugvoid

This method returns an undefined value.

@param message

Parameters:

  • message (Object, nil)


1000
# File 'sig/checkoff.rbs', line 1000

def debug: (?Object? message) -> void

#errorvoid

This method returns an undefined value.

@param message

Parameters:

  • message (Object, nil)


991
# File 'sig/checkoff.rbs', line 991

def error: (?Object? message) -> void

#finervoid

This method returns an undefined value.

@param message

Parameters:

  • message (Object, nil)


1003
# File 'sig/checkoff.rbs', line 1003

def finer: (?Object? message) -> void

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

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project @param project

@param field_name

@param period — See Checkoff::Timing#in_period? - :now_or_before,:this_week

Parameters:

  • project (Asana::Resources::Project)
  • field_name (Symbol, ::Array[untyped])
  • period (Symbol, [Symbol, Integer])

Returns:

  • (Boolean)


224
225
226
227
228
229
# File 'lib/checkoff/projects.rb', line 224

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

#infovoid

This method returns an undefined value.

@param message

Parameters:

  • message (Object, nil)


997
# File 'sig/checkoff.rbs', line 997

def info: (?Object? message) -> void

#log_levelSymbol

@sg-ignore

Returns:

  • (Symbol)


1006
# File 'sig/checkoff.rbs', line 1006

def log_level: () -> Symbol

#logger::Logger

Returns:

  • (::Logger)


988
# File 'sig/checkoff.rbs', line 988

def logger: () -> ::Logger

#my_tasks(workspace_name) ⇒ Asana::Resources::Project

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project @param workspace_name

Parameters:

  • workspace_name (String, Symbol)

Returns:

  • (Asana::Resources::Project)


261
262
263
264
265
266
267
# File 'lib/checkoff/projects.rb', line 261

def my_tasks(workspace_name)
  workspace = @workspaces.workspace_or_raise(workspace_name)
  result = client.user_task_lists.get_user_task_list_for_user(user_gid: 'me',
                                                              workspace: workspace.gid)
  gid = result.gid
  projects.find_by_id(gid)
end

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

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project pulls an Asana API project class given a name

@param workspace_name

@param project_name — - :my_tasks or a project name

@param extra_fields

Parameters:

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

Returns:

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


105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/checkoff/projects.rb', line 105

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:)
    # @type <Asana::Resources::Project,nil>
    # @sg-ignore
    project = ps.find { _1.name == project_name }
    project_by_gid(project.gid, extra_fields:) unless project.nil?
  end
end

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

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project @param gid

@param extra_fields

Parameters:

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

Returns:

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


137
138
139
140
141
142
# File 'lib/checkoff/projects.rb', line 137

def project_by_gid(gid, extra_fields: [])
  projects.find_by_id(gid, options: project_options(extra_project_fields: extra_fields))
rescue Asana::Errors::NotFound => e
  debug e
  nil
end

#project_fields(extra_project_fields: []) ⇒ ::Array[String]

@param extra_project_fields

Parameters:

  • extra_project_fields: (::Array[String]) (defaults to: [])

Returns:

  • (::Array[String])


86
87
88
# File 'lib/checkoff/projects.rb', line 86

def project_fields(extra_project_fields: [])
  (%w[name custom_fields] + extra_project_fields).sort.uniq
end

#project_options(extra_project_fields: []) ⇒ ::Hash[Symbol, Object]

Default options used in Asana API to pull projects

@param extra_project_fields

Parameters:

  • extra_project_fields: (::Array[String]) (defaults to: [])

Returns:

  • (::Hash[Symbol, Object])


95
96
97
# File 'lib/checkoff/projects.rb', line 95

def project_options(extra_project_fields: [])
  { fields: project_fields(extra_project_fields:) }
end

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

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project @sg-ignore

@param workspace_name

@param project_name — - :my_tasks or a project name

@param extra_fields

Parameters:

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

Returns:

  • (Asana::Resources::Project)


125
126
127
128
129
130
# File 'lib/checkoff/projects.rb', line 125

def project_or_raise(workspace_name, project_name, extra_fields: [])
  p = project(workspace_name, project_name, 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

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project 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.

@param project

@param period — See Checkoff::Timing#in_period? - :now_or_before,:this_week

Parameters:

  • project (Asana::Resources::Project)
  • period: (Symbol, [Symbol, Integer]) (defaults to: :now_or_before)

Returns:

  • (Boolean)


217
218
219
# File 'lib/checkoff/projects.rb', line 217

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

#project_to_h(project_obj, project: :not_specified) ⇒ ::Hash[untyped, untyped]

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project @param project_obj

@param project — - :not_specified, :my_tasks or a project name

Parameters:

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

Returns:

  • (::Hash[untyped, untyped])


204
205
206
# File 'lib/checkoff/projects.rb', line 204

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

#projectsAsana::ProxiedResourceClasses::Project

sord warn - Asana::ProxiedResourceClasses::Project wasn't able to be resolved to a constant in this project

Returns:

  • (Asana::ProxiedResourceClasses::Project)


253
254
255
# File 'lib/checkoff/projects.rb', line 253

def projects
  client.projects
end

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

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project @param workspace_name

@param extra_fields

Parameters:

  • workspace_name (String, Symbol)
  • extra_fields: (::Array[String]) (defaults to: [])

Returns:

  • (::Enumerable[Asana::Resources::Project])


189
190
191
192
193
194
195
196
197
# File 'lib/checkoff/projects.rb', line 189

def projects_by_workspace_name(workspace_name, extra_fields: [])
  workspace = @workspaces.workspace_or_raise(workspace_name)
  # 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: project_options(extra_project_fields: extra_fields)).to_a
end

#task_fields(extra_fields: []) ⇒ ::Array[String]

@param extra_fields

Parameters:

  • extra_fields: (::Array[String]) (defaults to: [])

Returns:

  • (::Array[String])


60
61
62
63
64
# File 'lib/checkoff/projects.rb', line 60

def task_fields(extra_fields: [])
  (%w[name completed_at start_at start_on due_at due_on tags
      memberships.project.gid memberships.project.name
      memberships.section.name dependencies] + extra_fields).sort.uniq
end

#task_options(extra_fields: [], only_uncompleted: false) ⇒ ::Hash[Symbol, untyped]

Default options used in Asana API to pull tasks

@param extra_fields

@param only_uncompleted

Parameters:

  • extra_fields: (::Array[String]) (defaults to: [])
  • only_uncompleted: (Boolean) (defaults to: false)

Returns:

  • (::Hash[Symbol, untyped])


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

def task_options(extra_fields: [], only_uncompleted: false)
  options = {
    per_page: 100,
    options: {
      fields: task_fields(extra_fields:),
    },
  }
  options[:completed_since] = '9999-12-01' if only_uncompleted
  options
end

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

sord warn - Asana::Resources::Project wasn't able to be resolved to a constant in this project sord warn - Asana::Resources::Task wasn't able to be resolved to a constant in this project Pull task objects from a named project

@param project

@param only_uncompleted

@param extra_fields

Parameters:

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

Returns:

  • (::Enumerable[Asana::Resources::Task])


159
160
161
162
163
164
165
# File 'lib/checkoff/projects.rb', line 159

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

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

sord warn - Asana::Resources::Task wasn't able to be resolved to a constant in this project Pull task objects from a project identified by a gid

@param project_gid

@param only_uncompleted

@param extra_fields

Parameters:

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

Returns:

  • (::Enumerable[Asana::Resources::Task])


174
175
176
177
178
179
180
181
182
183
# File 'lib/checkoff/projects.rb', line 174

def tasks_from_project_gid(project_gid,
                           only_uncompleted: true,
                           extra_fields: [])
  options = task_options(extra_fields:, only_uncompleted:)
  options[:project] = project_gid
  # Note: 30 minute cache time on a raw Enumerable from SDK gives
  # 'Your pagination token has expired' errors.  So we go ahead
  # and eagerly evaluate here so we can enjoy the cache.
  client.tasks.find_all(**options).to_a
end

#warnvoid

This method returns an undefined value.

@param message

Parameters:

  • message (Object, nil)


994
# File 'sig/checkoff.rbs', line 994

def warn: (?Object? message) -> void