checkoff 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4eeb7148c4b835088d3fedc674bf3195b92c9889bfe935a745b50e0b7228c65
4
- data.tar.gz: 2a48471aae38c5ed10bed024968bb51ccd772f1e1efe3acd70b7a4c92bbb59ae
3
+ metadata.gz: 28bce7b1402a371b87f03a468cb1678cd02f7631a2a8f195a544b2bccc4af26e
4
+ data.tar.gz: f645e96e4526173f33e7b3140d9fec84b59330a4050819467a4456f0b9e10679
5
5
  SHA512:
6
- metadata.gz: cf4c95afee408b7937ea09c543c21e50b2855eba0393d9ac542e8d67f4eeb9c02c67b82cb23b7b00a81ca09f9678fafbe294baf947d3fcf1418ecd0208947298
7
- data.tar.gz: 3ec3e6ef6b0a6c1583a96326cd0fa545b500f61e21ddc97624aeab31dadcd9125928d2bc78bbb8e7ec2827837d700ab651d5bb26a201ddf2a14acb862c246777
6
+ metadata.gz: 1503cc4b41f8297a806b57311c2f7f3e0e6d7b93027109125c985b4dba056e2709fdcec43d5ca312f9778ba044d67c28e8a5c055a692b7067ebf442491de912e
7
+ data.tar.gz: 1b30b11537a9608e84ec1434c67a47579e0d6d2a8a88ee79084de24efc39c18e8b10fc1af5be5ccf7b4aac17509b4b16d540d2f4f2304b61f3100b0006ff2af4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- checkoff (0.11.1)
4
+ checkoff (0.12.0)
5
5
  activesupport
6
6
  asana (> 0.10.0)
7
7
  cache_method
@@ -11,7 +11,7 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activesupport (6.1.3.2)
14
+ activesupport (6.1.4)
15
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
16
16
  i18n (>= 1.6, < 2)
17
17
  minitest (>= 5.1)
@@ -31,25 +31,29 @@ GEM
31
31
  concurrent-ruby (1.1.9)
32
32
  dalli (2.7.11)
33
33
  docile (1.4.0)
34
- faraday (1.4.2)
34
+ faraday (1.5.1)
35
35
  faraday-em_http (~> 1.0)
36
36
  faraday-em_synchrony (~> 1.0)
37
37
  faraday-excon (~> 1.1)
38
+ faraday-httpclient (~> 1.0.1)
38
39
  faraday-net_http (~> 1.0)
39
40
  faraday-net_http_persistent (~> 1.1)
41
+ faraday-patron (~> 1.0)
40
42
  multipart-post (>= 1.2, < 3)
41
43
  ruby2_keywords (>= 0.0.4)
42
44
  faraday-em_http (1.0.0)
43
45
  faraday-em_synchrony (1.0.0)
44
46
  faraday-excon (1.1.0)
47
+ faraday-httpclient (1.0.1)
45
48
  faraday-net_http (1.0.1)
46
- faraday-net_http_persistent (1.1.0)
49
+ faraday-net_http_persistent (1.2.0)
50
+ faraday-patron (1.0.0)
47
51
  faraday_middleware (1.0.0)
48
52
  faraday (~> 1.0)
49
53
  faraday_middleware-multi_json (0.0.6)
50
54
  faraday_middleware
51
55
  multi_json
52
- gli (2.20.0)
56
+ gli (2.20.1)
53
57
  i18n (1.8.10)
54
58
  concurrent-ruby (~> 1.0)
55
59
  imagen (0.1.8)
@@ -96,7 +100,7 @@ GEM
96
100
  rubocop-rake (0.5.1)
97
101
  rubocop
98
102
  ruby-progressbar (1.11.0)
99
- ruby2_keywords (0.0.4)
103
+ ruby2_keywords (0.0.5)
100
104
  rugged (1.1.0)
101
105
  simplecov (0.21.2)
102
106
  docile (~> 1.1)
@@ -136,4 +140,4 @@ DEPENDENCIES
136
140
  undercover
137
141
 
138
142
  BUNDLED WITH
139
- 2.2.19
143
+ 2.2.24
data/README.md CHANGED
@@ -12,7 +12,7 @@ $ checkoff --help
12
12
  View tasks:
13
13
  checkoff view workspace project [section]
14
14
 
15
- 'project' can be set to a project name, or :my_tasks, :my_tasks_upcoming, :my_tasks_new, or :my_tasks_today
15
+ 'project' can be set to a project name, or :my_tasks for your user task list.
16
16
  ```
17
17
 
18
18
  Let's say we have a project like this:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "result": {
3
- "line": 94.61,
4
- "branch": 71.42
3
+ "line": 97.0,
4
+ "branch": 80.95
5
5
  }
6
6
  }
@@ -35,6 +35,17 @@ module Checkoff
35
35
  @workspaces.client
36
36
  end
37
37
 
38
+ # Default options used in Asana API to pull taskso
39
+ def task_options
40
+ {
41
+ per_page: 100,
42
+ options: {
43
+ fields: %w[name completed_at due_at due_on tags
44
+ memberships.project.gid memberships.section.name dependencies],
45
+ },
46
+ }
47
+ end
48
+
38
49
  # pulls an Asana API project class given a name
39
50
  def project(workspace_name, project_name)
40
51
  if project_name.is_a?(Symbol) && project_name.to_s.start_with?('my_tasks')
@@ -84,15 +95,5 @@ module Checkoff
84
95
  gid = result.gid
85
96
  projects.find_by_id(gid)
86
97
  end
87
-
88
- def task_options
89
- {
90
- per_page: 100,
91
- options: {
92
- fields: %w[name completed_at due_at due_on assignee_status tags
93
- memberships.project.gid memberships.section.name dependencies],
94
- },
95
- }
96
- end
97
98
  end
98
99
  end
@@ -4,7 +4,6 @@ require 'forwardable'
4
4
 
5
5
  module Checkoff
6
6
  # Query different sections of Asana projects
7
- # rubocop:disable Metrics/ClassLength
8
7
  class Sections
9
8
  MINUTE = 60
10
9
  LONG_CACHE_TIME = MINUTE * 15
@@ -23,118 +22,74 @@ module Checkoff
23
22
  @time = time
24
23
  end
25
24
 
26
- # Given a list of tasks, pull a Hash of tasks with section name -> task list
27
- def by_section(tasks, project_gid)
28
- by_section = {}
29
- tasks.each do |task|
30
- file_task_by_section(by_section, task, project_gid)
31
- end
32
- by_section
33
- end
34
- cache_method :by_section, LONG_CACHE_TIME
35
-
36
- # Given a project object, pull all tasks, then provide a Hash of
37
- # tasks with section name -> task list of the uncompleted tasks
38
- def tasks_by_section_for_project(project)
39
- raw_tasks = projects.tasks_from_project(project)
40
- active_tasks = projects.active_tasks(raw_tasks)
41
- by_section(active_tasks, project.gid)
25
+ # Returns a list of Asana API section objects for a given project
26
+ def sections_or_raise(workspace_name, project_name)
27
+ project = project_or_raise(workspace_name, project_name)
28
+ client.sections.get_sections_for_project(project_gid: project.gid)
42
29
  end
43
30
 
44
31
  # Given a workspace name and project name, then provide a Hash of
45
32
  # tasks with section name -> task list of the uncompleted tasks
46
33
  def tasks_by_section(workspace_name, project_name)
47
34
  project = project_or_raise(workspace_name, project_name)
48
- case project_name
49
- when :my_tasks, :my_tasks_new, :my_tasks_today, :my_tasks_upcoming
50
- user_task_list_by_section(workspace_name, project_name)
51
- else
52
- tasks_by_section_for_project(project)
53
- end
35
+ tasks_by_section_for_project(project)
54
36
  end
55
37
  cache_method :tasks_by_section, SHORT_CACHE_TIME
56
38
 
57
39
  # XXX: Rename to section_tasks
58
40
  #
59
41
  # Pulls task objects from a specified section
60
- def tasks(workspace_name, project_name, section_name)
61
- tasks_by_section(workspace_name, project_name).fetch(section_name, [])
42
+ def tasks(workspace_name, project_name, section_name,
43
+ only_uncompleted: true,
44
+ extra_fields: [])
45
+ section = section_or_raise(workspace_name, project_name, section_name)
46
+ options = projects.task_options
47
+ # asana-0.10.3 gem doesn't support per_page - not sure if API
48
+ # itself does
49
+ options.delete(:per_page)
50
+ options[:options][:fields] += extra_fields
51
+ client.tasks.get_tasks_for_section(section_gid: section.gid,
52
+ **options).to_a
62
53
  end
63
54
  cache_method :tasks, SHORT_CACHE_TIME
64
55
 
65
56
  # Pulls just names of tasks from a given section.
66
57
  def section_task_names(workspace_name, project_name, section_name)
67
58
  tasks = tasks(workspace_name, project_name, section_name)
68
- if tasks.nil?
69
- by_section = tasks_by_section(workspace_name, project_name)
70
- desc = "#{workspace_name} | #{project_name} | #{section_name}"
71
- raise "Could not find task names for #{desc}. " \
72
- "Valid sections: #{by_section.keys}"
73
- end
74
59
  tasks.map(&:name)
75
60
  end
76
61
  cache_method :section_task_names, SHORT_CACHE_TIME
77
62
 
78
- # returns if a task's due field is at or before the current date/time
79
- def task_due?(task)
80
- if task.due_at
81
- Time.parse(task.due_at) <= time.now
82
- elsif task.due_on
83
- Date.parse(task.due_on) <= time.today
84
- else
85
- true # set a due date if you don't want to do this now
86
- end
87
- end
88
-
89
63
  private
90
64
 
91
- def_delegators :@projects, :client
92
-
93
- def file_task_by_section(by_section, task, project_gid)
94
- membership = task.memberships.find { |m| m['project']['gid'] == project_gid }
95
- raise "Could not find task in project_gid #{project_gid}: #{task}" if membership.nil?
96
-
97
- current_section = membership['section']['name']
98
- current_section = nil if current_section == '(no section)'
99
- by_section[current_section] ||= []
100
- by_section[current_section] << task
101
- end
102
-
103
- def legacy_tasks_by_section_for_project(project)
65
+ # Given a project object, pull all tasks, then provide a Hash of
66
+ # tasks with section name -> task list of the uncompleted tasks
67
+ def tasks_by_section_for_project(project)
104
68
  raw_tasks = projects.tasks_from_project(project)
105
69
  active_tasks = projects.active_tasks(raw_tasks)
106
- legacy_by_section(active_tasks)
70
+ by_section(active_tasks, project.gid)
107
71
  end
108
72
 
109
- def legacy_file_task_by_section(current_section, by_section, task)
110
- if task.name =~ /:$/
111
- current_section = task.name
112
- by_section[current_section] = []
113
- else
114
- by_section[current_section] ||= []
115
- by_section[current_section] << task
116
- end
117
- [current_section, by_section]
118
- end
73
+ def_delegators :@projects, :client
119
74
 
120
- def legacy_by_section(tasks)
121
- current_section = nil
75
+ # Given a list of tasks, pull a Hash of tasks with section name -> task list
76
+ def by_section(tasks, project_gid)
122
77
  by_section = {}
123
78
  tasks.each do |task|
124
- current_section, by_section =
125
- legacy_file_task_by_section(current_section, by_section, task)
79
+ file_task_by_section(by_section, task, project_gid)
126
80
  end
127
81
  by_section
128
82
  end
83
+ cache_method :by_section, LONG_CACHE_TIME
129
84
 
130
- def legacy_tasks_by_section_for_project_and_assignee_status(project,
131
- assignee_status)
132
- raw_tasks = projects.tasks_from_project(project)
133
- by_assignee_status =
134
- projects.active_tasks(raw_tasks)
135
- .group_by(&:assignee_status)
136
- active_tasks = by_assignee_status[assignee_status]
137
- legacy_by_section(active_tasks)
85
+ def file_task_by_section(by_section, task, project_gid)
86
+ membership = task.memberships.find { |m| m['project']['gid'] == project_gid }
87
+ raise "Could not find task in project_gid #{project_gid}: #{task}" if membership.nil?
88
+
89
+ current_section = membership['section']['name']
90
+ current_section = nil if current_section == '(no section)'
91
+ by_section[current_section] ||= []
92
+ by_section[current_section] << task
138
93
  end
139
94
 
140
95
  def project_or_raise(workspace_name, project_name)
@@ -146,49 +101,20 @@ module Checkoff
146
101
  project
147
102
  end
148
103
 
149
- def verify_legacy_user_task_list!(workspace_name)
150
- return unless user_task_list_migrated_to_real_sections?(workspace_name)
151
-
152
- raise NotImplementedError, 'Section-based user task lists not yet supported'
104
+ def section(workspace_name, project_name, section_name)
105
+ sections = sections_or_raise(workspace_name, project_name)
106
+ sections.find { |section| section.name.chomp(':') == section_name.chomp(':') }
153
107
  end
154
108
 
155
- ASSIGNEE_STATUS_BY_PROJECT_NAME = {
156
- my_tasks_new: 'inbox',
157
- my_tasks_today: 'today',
158
- my_tasks_upcoming: 'upcoming',
159
- }.freeze
160
-
161
- def user_task_list_by_section(workspace_name, project_name)
162
- verify_legacy_user_task_list!(workspace_name)
163
-
164
- project = projects.project(workspace_name, project_name)
165
- if project_name == :my_tasks
166
- legacy_tasks_by_section_for_project(project)
167
- else
168
- legacy_tasks_by_section_for_project_and_assignee_status(project,
169
- ASSIGNEE_STATUS_BY_PROJECT_NAME.fetch(project_name))
170
- end
171
- end
172
-
173
- def user_task_list_migrated_to_real_sections?(workspace_name)
174
- workspace = workspaces.workspace_by_name(workspace_name)
175
- result = client.user_task_lists.get_user_task_list_for_user(user_gid: 'me',
176
- workspace: workspace.gid)
177
- result.migration_status != 'not_migrated'
178
- end
109
+ def section_or_raise(workspace_name, project_name, section_name)
110
+ section = section(workspace_name, project_name, section_name)
111
+ if section.nil?
112
+ valid_sections = sections_or_raise(workspace_name, project_name).map(&:name)
179
113
 
180
- def project_task_names(workspace_name, project_name)
181
- by_section = tasks_by_section(workspace_name, project_name)
182
- by_section.flat_map do |section_name, tasks|
183
- task_names = tasks.map(&:name)
184
- if section_name.nil?
185
- task_names
186
- else
187
- [section_name, task_names]
188
- end
114
+ raise "Could not find section #{section_name} under project #{project_name} " \
115
+ "under workspace #{workspace_name}. Valid sections: #{valid_sections}"
189
116
  end
117
+ section
190
118
  end
191
- cache_method :project_task_names, SHORT_CACHE_TIME
192
119
  end
193
- # rubocop:enable Metrics/ClassLength
194
120
  end
@@ -54,10 +54,6 @@ module Checkoff
54
54
  @projects ||= @sections.projects
55
55
  end
56
56
 
57
- def tasks_minus_sections(tasks)
58
- @sections.by_section(tasks).values.flatten
59
- end
60
-
61
57
  def default_assignee_gid
62
58
  @config.fetch(:default_assignee_gid)
63
59
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Checkoff
4
4
  # Version of library
5
- VERSION = '0.11.1'
5
+ VERSION = '0.12.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checkoff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vince Broz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-11 00:00:00.000000000 Z
11
+ date: 2021-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport