checkoff 0.156.0 → 0.158.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7e1681e39cd8f9271a9314abcf687982bf375b762d3c64cf5e7c43f3b61b589
4
- data.tar.gz: 2fe95b6c69f11f2b545afae74e8c7983773b229045cdcbdb7bb98557466f31c6
3
+ metadata.gz: 3411417f4aa2d4585bbffe2abbe5d035e6c87df952f7db9c13b1c0233800f65a
4
+ data.tar.gz: 84a4da9aa7cb6d34d5e3af3677372f16b7377aa373486ddc5db34fc7b29bb7c6
5
5
  SHA512:
6
- metadata.gz: a6197bbbe0a690f572f2776111b0be018d26848a926c5d7b801d310c2101f6c2f96bd557b925f24de57990b7aed1a66630f7fbee9c52951514d95672cde3d811
7
- data.tar.gz: e23898385246ac5ff3c2c331d2e87b76ba6d1e081d7adec40c8b26646bb9b42866de6ba84247e1ba2d4ca89a054be4fe44ea9494cce96a019d99e291fd6279f2
6
+ metadata.gz: d58a2d975ea40a4de969af0149a84b118efdf36f24d0c9bae40203bb535d032fc8b4d2a912185392d4bd7280d1e356df19f521ad14b6f089cdcc8de281548658
7
+ data.tar.gz: 8d6f4e1c7a7d0d09fcc84e1eb1c0a72f4ab4ed9ba30bdddff89c9239e8e60e882a5377de31846bec7d7a7938a951b27e8a23817c84e518a04abb20041e1096bf
data/Gemfile.lock CHANGED
@@ -12,7 +12,7 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- checkoff (0.156.0)
15
+ checkoff (0.158.0)
16
16
  activesupport
17
17
  asana (> 0.10.0)
18
18
  cache_method
@@ -111,21 +111,39 @@ module Checkoff
111
111
  tasks.select { |task| task.completed_at.nil? }
112
112
  end
113
113
 
114
- # pull task objects from a named project
114
+ # Pull task objects from a named project
115
+ #
115
116
  # @param [Asana::Resources::Project] project
116
117
  # @param [Boolean] only_uncompleted
117
118
  # @param [Array<String>] extra_fields
119
+ #
118
120
  # @return [Enumerable<Asana::Resources::Task>]
119
121
  def tasks_from_project(project,
120
122
  only_uncompleted: true,
121
123
  extra_fields: [])
124
+ tasks_from_project_gid(project.gid,
125
+ only_uncompleted: only_uncompleted,
126
+ extra_fields: extra_fields)
127
+ end
128
+ cache_method :tasks_from_project, SHORT_CACHE_TIME
129
+
130
+ # Pull task objects from a project identified by a gid
131
+ #
132
+ # @param [String] project_gid
133
+ # @param [Boolean] only_uncompleted
134
+ # @param [Array<String>] extra_fields
135
+ #
136
+ # @return [Enumerable<Asana::Resources::Task>]
137
+ def tasks_from_project_gid(project_gid,
138
+ only_uncompleted: true,
139
+ extra_fields: [])
122
140
  options = task_options
123
141
  options[:completed_since] = '9999-12-01' if only_uncompleted
124
- options[:project] = project.gid
142
+ options[:project] = project_gid
125
143
  options[:options][:fields] += extra_fields
126
144
  client.tasks.find_all(**options)
127
145
  end
128
- cache_method :tasks_from_project, SHORT_CACHE_TIME
146
+ cache_method :tasks_from_project_gid, SHORT_CACHE_TIME
129
147
 
130
148
  # @param [String] workspace_name
131
149
  # @param [Array<String>] extra_fields
@@ -84,30 +84,29 @@ module Checkoff
84
84
  #
85
85
  # @param [Hash<Symbol, Object>] api_params
86
86
  # @param [String] workspace_gid
87
- # @param [String] url
88
87
  # @param [Array<String>] extra_fields
89
88
  # @param [Array] task_selector
89
+ # @param [Boolean] fetch_all Ensure all results are provided by manually paginating
90
90
  #
91
91
  # @return [Enumerable<Asana::Resources::Task>]
92
- def raw_task_search(api_params, workspace_gid:, extra_fields: [], task_selector: [])
92
+ def raw_task_search(api_params,
93
+ workspace_gid:, extra_fields: [], task_selector: [],
94
+ fetch_all: true)
93
95
  # @sg-ignore
94
- path = "/workspaces/#{workspace_gid}/tasks/search"
95
- options = calculate_api_options(extra_fields)
96
- tasks = @asana_resources_collection_class.new(parse(client.get(path,
97
- params: api_params,
98
- options: options)),
99
- type: Asana::Resources::Task,
100
- client: client)
101
-
102
- if tasks.length == 100
103
- raise 'Too many results returned. ' \
104
- 'Please narrow your search in ways expressible through task search API: ' \
105
- 'https://developers.asana.com/reference/searchtasksforworkspace'
96
+ tasks = api_task_search_request(api_params, workspace_gid: workspace_gid, extra_fields: extra_fields)
97
+
98
+ if fetch_all && tasks.count == 100
99
+ # @sg-ignore
100
+ tasks = iterated_raw_task_search(api_params, workspace_gid: workspace_gid, extra_fields: extra_fields)
106
101
  end
107
102
 
108
- debug { "#{tasks.length} raw tasks returned" }
103
+ debug { "#{tasks.count} raw tasks returned" }
104
+
105
+ return tasks if task_selector.empty?
109
106
 
110
- tasks.select { |task| task_selectors.filter_via_task_selector(task, task_selector) }
107
+ tasks.select do |task|
108
+ task_selectors.filter_via_task_selector(task, task_selector)
109
+ end
111
110
  end
112
111
 
113
112
  # @return [Hash]
@@ -117,6 +116,79 @@ module Checkoff
117
116
 
118
117
  private
119
118
 
119
+ # Perform a search using the Asana Task Search API:
120
+ #
121
+ # https://developers.asana.com/reference/searchtasksforworkspace
122
+ #
123
+ # @param [Hash<Symbol, Object>] api_params
124
+ # @param [String] workspace_gid
125
+ # @param [Array<String>] extra_fields
126
+ #
127
+ # @return [Enumerable<Asana::Resources::Task>]
128
+ def api_task_search_request(api_params, workspace_gid:, extra_fields:)
129
+ path = "/workspaces/#{workspace_gid}/tasks/search"
130
+ options = calculate_api_options(extra_fields)
131
+ @asana_resources_collection_class.new(parse(client.get(path,
132
+ params: api_params,
133
+ options: options)),
134
+ type: Asana::Resources::Task,
135
+ client: client)
136
+ end
137
+
138
+ # Perform a search using the Asana Task Search API and use manual pagination to
139
+ # ensure all results are returned:
140
+ #
141
+ # https://developers.asana.com/reference/searchtasksforworkspace
142
+ #
143
+ # "However, you can paginate manually by sorting the search
144
+ # results by their creation time and then modifying each
145
+ # subsequent query to exclude data you have already seen." -
146
+ # see sort_by field at
147
+ # https://developers.asana.com/reference/searchtasksforworkspace
148
+ #
149
+ # @param [Hash<Symbol, Object>] api_params
150
+ # @param [String] workspace_gid
151
+ # @param [String] url
152
+ # @param [Array<String>] extra_fields
153
+ # @param [Boolean] fetch_all Ensure all results are provided by manually paginating
154
+ #
155
+ # @return [Enumerable<Asana::Resources::Task>]
156
+ def iterated_raw_task_search(api_params, workspace_gid:, extra_fields:)
157
+ # https://developers.asana.com/reference/searchtasksforworkspace
158
+ tasks = []
159
+ new_api_params = api_params.dup
160
+ original_sort_by = new_api_params.delete('sort_by')
161
+ # defaults to false
162
+ original_sort_ascending = new_api_params.delete('sort_ascending')
163
+ original_created_at_before = new_api_params.delete('created_at.before')
164
+ raise 'Teach me how to handle original_created_at_before' unless original_created_at_before.nil?
165
+
166
+ new_api_params['sort_by'] = 'created_at'
167
+
168
+ Kernel.loop do
169
+ # Get the most recently created results, then iterate on until we're out of results
170
+
171
+ # @type [Array<Asana::Resources::Task>]
172
+ task_batch = raw_task_search(new_api_params,
173
+ workspace_gid: workspace_gid, extra_fields: extra_fields + ['created_appt'],
174
+ fetch_all: false).to_a
175
+ oldest = task_batch.to_a.last
176
+
177
+ break if oldest.nil?
178
+
179
+ new_api_params['created_at.before'] = oldest.created_at
180
+
181
+ tasks.concat(task_batch.to_a)
182
+ end
183
+ unless original_sort_by.nil? || original_sort_by == 'created_at'
184
+ raise "Teach me how to handle original_sort_by: #{original_sort_by.inspect}"
185
+ end
186
+
187
+ raise 'Teach me how to handle original_sort_ascending' unless original_sort_ascending.nil?
188
+
189
+ tasks
190
+ end
191
+
120
192
  # @param [Array<String>] extra_fields
121
193
  # @return [Hash<Symbol, Object>]
122
194
  def calculate_api_options(extra_fields)
@@ -3,5 +3,5 @@
3
3
  # Command-line and gem client for Asana (unofficial)
4
4
  module Checkoff
5
5
  # Version of library
6
- VERSION = '0.156.0'
6
+ VERSION = '0.158.0'
7
7
  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.156.0
4
+ version: 0.158.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: 2023-12-14 00:00:00.000000000 Z
11
+ date: 2023-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport