Class: Checkoff::Sections

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

Overview

Query different sections of Asana projects

Constant Summary collapse

MINUTE =
60
HOUR =
MINUTE * 60
REALLY_LONG_CACHE_TIME =
MINUTE * 30
LONG_CACHE_TIME =
MINUTE * 15
SHORT_CACHE_TIME =
MINUTE * 5

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

#debug, #error, #finer, #info, #logger, #warn

Constructor Details

#initialize(config: Checkoff::Internal::ConfigLoader.load(:asana), client: Checkoff::Clients.new(config:).client, projects: Checkoff::Projects.new(config:, client:), workspaces: Checkoff::Workspaces.new(config:, client:), time: Time) ⇒ Sections

Returns a new instance of Sections.

Parameters:

  • config (Checkoff::Internal::EnvFallbackConfigLoader, Hash) (defaults to: Checkoff::Internal::ConfigLoader.load(:asana))
  • client (Asana::Client) (defaults to: Checkoff::Clients.new(config:).client)
  • projects (Checkoff::Projects) (defaults to: Checkoff::Projects.new(config:, client:))
  • workspaces (Checkoff::Workspaces) (defaults to: Checkoff::Workspaces.new(config:, client:))
  • time (Class<Time>) (defaults to: Time)


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

def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
               client: Checkoff::Clients.new(config:).client,
               projects: Checkoff::Projects.new(config:,
                                                client:),
               workspaces: Checkoff::Workspaces.new(config:,
                                                    client:),
               time: Time)
  @projects = projects
  @workspaces = workspaces
  @my_tasks = Checkoff::MyTasks
    .new(config:, projects:, client:)
  @client = client
  @time = time
end

Instance Attribute Details

#my_tasksCheckoff::MyTasks (readonly)

Returns:



35
36
37
# File 'lib/checkoff/sections.rb', line 35

def my_tasks
  @my_tasks
end

#projectsCheckoff::Projects (readonly)

Returns:



26
27
28
# File 'lib/checkoff/sections.rb', line 26

def projects
  @projects
end

#timeClass<Time> (readonly)

Returns:

  • (Class<Time>)


32
33
34
# File 'lib/checkoff/sections.rb', line 32

def time
  @time
end

#workspacesCheckoff::Workspaces (readonly)



29
30
31
# File 'lib/checkoff/sections.rb', line 29

def workspaces
  @workspaces
end

Instance Method Details

#as_cache_keyHash

Returns:

  • (Hash)


213
214
215
# File 'lib/checkoff/sections.rb', line 213

def as_cache_key
  {}
end

#previous_section(section) ⇒ Asana::Resources::Section?

Parameters:

  • section (Asana::Resources::Section)

Returns:

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


186
187
188
189
190
191
192
193
194
195
196
# File 'lib/checkoff/sections.rb', line 186

def previous_section(section)
  sections = sections_by_project_gid(section.project.fetch('gid'))

  # @type [Array<Asana::Resources::Section>]
  sections = sections.to_a

  index = sections.find_index { |s| s.gid == section.gid }
  return nil if index.nil? || index.zero?

  sections[index - 1]
end

#section(workspace_name, project_name, section_name, extra_section_fields: []) ⇒ Asana::Resources::Section?

@sg-ignore

Parameters:

  • workspace_name (String)
  • project_name (String, Symbol)
  • section_name (String, nil)
  • extra_section_fields (Array<String>) (defaults to: [])

Returns:

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


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

def section(workspace_name, project_name, section_name, extra_section_fields: [])
  sections = sections_or_raise(workspace_name, project_name,
                               extra_fields: extra_section_fields)
  sections.find { |section| section_key(T.cast(section.name, String))&.chomp(':') == section_name&.chomp(':') }
end

#section_by_gid(gid) ⇒ Asana::Resources::Section?

Parameters:

  • gid (String)

Returns:

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


202
203
204
205
206
207
208
209
# File 'lib/checkoff/sections.rb', line 202

def section_by_gid(gid)
  options = {}
  Asana::Resources::Section.new(parse(client.get("/sections/#{gid}", options:)).first,
                                client:)
rescue Asana::Errors::NotFound => e
  debug e
  nil
end

#section_key(name) ⇒ String?

Parameters:

  • name (String)

Returns:

  • (String, nil)


176
177
178
179
180
181
# File 'lib/checkoff/sections.rb', line 176

def section_key(name)
  inbox_section_names = ['(no section)', 'Untitled section', 'Inbox', 'Recently assigned']
  return nil if inbox_section_names.include?(name)

  name
end

#section_or_raise(workspace_name, project_name, section_name, extra_section_fields: []) ⇒ Asana::Resources::Section

@sg-ignore

Parameters:

  • workspace_name (String)
  • project_name (String, Symbol)
  • section_name (String, nil)
  • extra_section_fields (Array<String>) (defaults to: [])

Returns:

  • (Asana::Resources::Section)


160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/checkoff/sections.rb', line 160

def section_or_raise(workspace_name, project_name, section_name, extra_section_fields: [])
  s = section(workspace_name, project_name, section_name,
              extra_section_fields:)
  if s.nil?
    valid_sections = sections_or_raise(workspace_name, project_name,
                                       extra_fields: extra_section_fields).map(&:name)

    raise "Could not find section #{section_name.inspect} under project #{project_name.inspect} " \
          "under workspace #{workspace_name.inspect}.  Valid sections: #{valid_sections.inspect}"
  end
  s
end

#section_task_names(workspace_name, project_name, section_name) ⇒ Array<String>

Pulls just names of tasks from a given section. @sg-ignore

Parameters:

  • workspace_name (String)
  • project_name (String, Symbol)
  • section_name (String, nil)

Returns:

  • (Array<String>)


146
147
148
149
150
# File 'lib/checkoff/sections.rb', line 146

def section_task_names(workspace_name, project_name, section_name)
  task_array = tasks(workspace_name, project_name, section_name)
  # @type [Array<String>]
  T.cast(task_array.map(&:name), T::Array[String])
end

#sections_by_project_gid(project_gid, extra_fields: []) ⇒ Enumerable<Asana::Resources::Section>

Returns a list of Asana API section objects for a given project GID

Parameters:

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

Returns:

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


74
75
76
77
78
# File 'lib/checkoff/sections.rb', line 74

def sections_by_project_gid(project_gid, extra_fields: [])
  fields = (%w[name] + extra_fields).sort.uniq
  client.sections.get_sections_for_project(project_gid:,
                                           options: { fields: })
end

#sections_or_raise(workspace_name, project_name, extra_fields: []) ⇒ Enumerable<Asana::Resources::Section>

Returns a list of Asana API section objects for a given project

Parameters:

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

Returns:

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


63
64
65
66
# File 'lib/checkoff/sections.rb', line 63

def sections_or_raise(workspace_name, project_name, extra_fields: [])
  project = project_or_raise(workspace_name, project_name)
  sections_by_project_gid(project.gid, extra_fields:)
end

#tasks(workspace_name, project_name, section_name, only_uncompleted: true, extra_fields: []) ⇒ Enumerable<Asana::Resources::Task>

Pulls task objects from a specified section

Parameters:

  • workspace_name (String)
  • project_name (String, Symbol)
  • section_name (String, nil)
  • only_uncompleted (Boolean) (defaults to: true)
  • extra_fields (Array<String>) (defaults to: [])

Returns:

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


125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/checkoff/sections.rb', line 125

def tasks(workspace_name, project_name, section_name,
          only_uncompleted: true,
          extra_fields: [])
  section = section_or_raise(workspace_name, project_name, section_name)
  options = projects.task_options(extra_fields:,
                                  only_uncompleted:)
  # 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.get_tasks(section: section.gid,
                         **options).to_a
end

#tasks_by_section(workspace_name, project_name, only_uncompleted: true, extra_fields: []) ⇒ Hash{String, nil => Enumerable<Asana::Resources::Task>}

Given a workspace name and project name, then provide a Hash of tasks with section name -> task list of the uncompleted tasks

Parameters:

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

Returns:

  • (Hash{String, nil => Enumerable<Asana::Resources::Task>})

Raises:

  • (ArgumentError)


88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/checkoff/sections.rb', line 88

def tasks_by_section(workspace_name,
                     project_name,
                     only_uncompleted: true,
                     extra_fields: [])
  raise ArgumentError, 'Provided nil workspace name' if T.unsafe(workspace_name).nil?
  raise ArgumentError, 'Provided nil project name' if T.unsafe(project_name).nil?

  project = project_or_raise(workspace_name, project_name)
  if project_name == :my_tasks
    my_tasks.tasks_by_section_for_my_tasks(project, only_uncompleted:, extra_fields:)
  else
    tasks_by_section_for_project(project, only_uncompleted:, extra_fields:)
  end
end

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

Parameters:

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

Returns:

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


108
109
110
111
112
113
114
# File 'lib/checkoff/sections.rb', line 108

def tasks_by_section_gid(section_gid,
                         only_uncompleted: true,
                         extra_fields: [])
  options = projects.task_options(extra_fields:,
                                  only_uncompleted:)
  client.tasks.get_tasks(section: section_gid, **options)
end