checkoff 0.110.0 → 0.112.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: a81e333f4fb405aaeadf79c3e41b65b8282ff8cbbcb5ffea959379e48e4209b0
4
- data.tar.gz: bcb8cbf57ccc8b906efbfb350aac27b233163a207e0d7ea08afbb9803f35ce00
3
+ metadata.gz: 393a800af57dad5fa9edde789dbe166b09ad79b374c2f7dcab230ee0050c49e7
4
+ data.tar.gz: a2e852b005e952bacf694e0684c97db27a0e53e2e68d79b471d7a2a8d66939ce
5
5
  SHA512:
6
- metadata.gz: d93bcd456a656aaf8dd375345715b9c39c272be02c9bac9345e84827c7aaa6809a8b0414103f38ac4492dd1690a6662b28c14a9ba50604942a81439aba2dd4b7
7
- data.tar.gz: 612fb95319d7be645abbebb0a45442ae9549f3a51f757903bcc4f372d65831c1c72e5fbf52b821b8bd970c27543ff96e0a4901cdcc774dc4d0e1eb164c9f00af
6
+ metadata.gz: 12769031da94bd1a7afc9afeccededab8f19506201f14c29d97cbacba7b3c0574f73d1a2bf52e9d6e511249d8f946d42295a110f0ef59f575e8d26eb6337377f
7
+ data.tar.gz: 6395b5b368b7b74a0173d4a62b5e55188348b9c8293865cba02163f7d9a85ede6d6a139ab001f74eaf7acd13b431af341bac7eddc5cff87ec780c4e67f6a7207
data/Gemfile.lock CHANGED
@@ -12,7 +12,7 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- checkoff (0.110.0)
15
+ checkoff (0.112.0)
16
16
  activesupport
17
17
  asana (> 0.10.0)
18
18
  cache_method
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'task/function_evaluator'
4
- require 'checkoff/internal/ready_between_relative'
5
4
  require 'checkoff/internal/task_timing'
6
5
 
7
6
  module Checkoff
@@ -146,93 +145,6 @@ module Checkoff
146
145
  end
147
146
  end
148
147
 
149
- # :ready_between_relative function
150
- class ReadyBetweenRelativePFunctionEvaluator < FunctionEvaluator
151
- FUNCTION_NAME = :ready_between_relative
152
-
153
- def matches?
154
- fn?(selector, FUNCTION_NAME)
155
- end
156
-
157
- # @param _index [Integer]
158
- def evaluate_arg?(_index)
159
- false
160
- end
161
-
162
- # @param task [Asana::Resources::Task]
163
- # @param beginning_num_days_from_now [Integer]
164
- # @param end_num_days_from_now [Integer]
165
- # @param ignore_dependencies [Boolean]
166
- #
167
- # @return [Boolean]
168
- def evaluate(task, beginning_num_days_from_now, end_num_days_from_now, ignore_dependencies: false)
169
- ready_between_relative = Checkoff::Internal::ReadyBetweenRelative.new(tasks: @tasks)
170
- ready_between_relative.ready_between_relative?(task,
171
- beginning_num_days_from_now, end_num_days_from_now,
172
- ignore_dependencies: ignore_dependencies)
173
- end
174
- end
175
-
176
- # :custom_field_less_than_n_days_from_now function
177
- class CustomFieldLessThanNDaysFromNowFunctionEvaluator < FunctionEvaluator
178
- FUNCTION_NAME = :custom_field_less_than_n_days_from_now
179
-
180
- def matches?
181
- fn?(selector, FUNCTION_NAME)
182
- end
183
-
184
- def evaluate_arg?(_index)
185
- false
186
- end
187
-
188
- # @param task [Asana::Resources::Task]
189
- # @param custom_field_name [String]
190
- # @param num_days [Integer]
191
- # @return [Boolean]
192
- def evaluate(task, custom_field_name, num_days)
193
- custom_field = @custom_fields.resource_custom_field_by_name_or_raise(task, custom_field_name)
194
-
195
- # @sg-ignore
196
- # @type [String, nil]
197
- time_str = custom_field.fetch('display_value')
198
- return false if time_str.nil?
199
-
200
- time = Time.parse(time_str)
201
- n_days_from_now = (Time.now + (num_days * 24 * 60 * 60))
202
- time < n_days_from_now
203
- end
204
- end
205
-
206
- # :custom_field_greater_than_or_equal_to_n_days_from_now function
207
- class CustomFieldGreaterThanOrEqualToNDaysFromNowFunctionEvaluator < FunctionEvaluator
208
- FUNCTION_NAME = :custom_field_greater_than_or_equal_to_n_days_from_now
209
-
210
- def matches?
211
- fn?(selector, FUNCTION_NAME)
212
- end
213
-
214
- def evaluate_arg?(_index)
215
- false
216
- end
217
-
218
- # @param task [Asana::Resources::Task]
219
- # @param custom_field_name [String]
220
- # @param num_days [Integer]
221
- # @return [Boolean]
222
- def evaluate(task, custom_field_name, num_days)
223
- custom_field = @custom_fields.resource_custom_field_by_name_or_raise(task, custom_field_name)
224
-
225
- # @sg-ignore
226
- # @type [String, nil]
227
- time_str = custom_field.fetch('display_value')
228
- return false if time_str.nil?
229
-
230
- time = Time.parse(time_str)
231
- n_days_from_now = (Time.now + (num_days * 24 * 60 * 60))
232
- time >= n_days_from_now
233
- end
234
- end
235
-
236
148
  # :last_story_created_less_than_n_days_ago function
237
149
  class LastStoryCreatedLessThanNDaysAgoFunctionEvaluator < FunctionEvaluator
238
150
  FUNCTION_NAME = :last_story_created_less_than_n_days_ago
@@ -6,9 +6,14 @@ module Checkoff
6
6
  class TaskTiming
7
7
  # @param time_class [Class<Time>]
8
8
  # @param date_class [Class<Date>]
9
- def initialize(time_class: Time, date_class: Date)
9
+ # @param client [Asana::Client]
10
+ # @param custom_fields [Checkoff::CustomFields]
11
+ def initialize(time_class: Time, date_class: Date,
12
+ client: Checkoff::Clients.new.client,
13
+ custom_fields: Checkoff::CustomFields.new(client: client))
10
14
  @time_class = time_class
11
15
  @date_class = date_class
16
+ @custom_fields = custom_fields
12
17
  end
13
18
 
14
19
  # @param task [Asana::Resources::Task]
@@ -56,6 +61,20 @@ module Checkoff
56
61
  return @time_class.parse(task.modified_at) unless task.modified_at.nil?
57
62
  end
58
63
 
64
+ # @param task [Asana::Resources::Task]
65
+ # @param custom_field_name [String]
66
+ #
67
+ # @return [Time, Date, nil]
68
+ def custom_field(task, custom_field_name)
69
+ custom_field = @custom_fields.resource_custom_field_by_name_or_raise(task, custom_field_name)
70
+ # @sg-ignore
71
+ # @type [String, nil]
72
+ time_str = custom_field.fetch('display_value')
73
+ return nil if time_str.nil?
74
+
75
+ Time.parse(time_str)
76
+ end
77
+
59
78
  # @param task [Asana::Resources::Task]
60
79
  # @param field_name [Symbol]
61
80
  #
@@ -70,6 +89,15 @@ module Checkoff
70
89
 
71
90
  return start_date_or_time(task) || due_date_or_time(task) if field_name == :ready
72
91
 
92
+ if field_name.is_a?(Array)
93
+ # @sg-ignore
94
+ # @type [Symbol]
95
+ actual_field_name = field_name.first
96
+ args = field_name[1..]
97
+
98
+ return custom_field(task, *args) if actual_field_name == :custom_field
99
+ end
100
+
73
101
  raise "Teach me how to handle field #{field_name}"
74
102
  end
75
103
  end
@@ -28,6 +28,7 @@ module Checkoff
28
28
  # @param workspaces [Checkoff::Workspaces]
29
29
  # @param sections [Checkoff::Sections]
30
30
  # @param portfolios [Checkoff::Portfolios]
31
+ # @param custom_fields [Checkoff::CustomFields]
31
32
  # @param time_class [Class<Time>]
32
33
  # @param date_class [Class<Date>]
33
34
  # @param asana_task [Class<Asana::Resources::Task>]
@@ -39,6 +40,8 @@ module Checkoff
39
40
  client: client),
40
41
  portfolios: Checkoff::Portfolios.new(config: config,
41
42
  client: client),
43
+ custom_fields: Checkoff::CustomFields.new(config: config,
44
+ client: client),
42
45
  time_class: Time,
43
46
  date_class: Date,
44
47
  asana_task: Asana::Resources::Task)
@@ -49,6 +52,7 @@ module Checkoff
49
52
  @asana_task = asana_task
50
53
  @client = client
51
54
  @portfolios = portfolios
55
+ @custom_fields = custom_fields
52
56
  @workspaces = workspaces
53
57
  @timing = Timing.new(today_getter: date_class, now_getter: time_class)
54
58
  end
@@ -73,7 +77,7 @@ module Checkoff
73
77
  end
74
78
 
75
79
  # @param task [Asana::Resources::Task]
76
- # @param field_name [Symbol]
80
+ # @param field_name [Symbol,Array]
77
81
  # @param period [Symbol<:now_or_before,:this_week>,Array] See Checkoff::Timing#in_period?_
78
82
  def in_period?(task, field_name, period)
79
83
  # @type [Date,Time,nil]
@@ -210,7 +214,9 @@ module Checkoff
210
214
 
211
215
  # @return [Checkoff::Internal::TaskTiming]
212
216
  def task_timing
213
- @task_timing ||= Checkoff::Internal::TaskTiming.new(time_class: @time_class, date_class: @date_class)
217
+ @task_timing ||= Checkoff::Internal::TaskTiming.new(time_class: @time_class, date_class: @date_class,
218
+ client: client,
219
+ custom_fields: custom_fields)
214
220
  end
215
221
 
216
222
  # @return [Checkoff::Internal::TaskHashes]
@@ -246,6 +252,9 @@ module Checkoff
246
252
  # @return [Checkoff::Timing]
247
253
  attr_reader :timing
248
254
 
255
+ # @return [Checkoff::CustomFields]
256
+ attr_reader :custom_fields
257
+
249
258
  # @return [Checkoff::Projects]
250
259
  def projects
251
260
  @projects ||= @sections.projects
@@ -68,6 +68,14 @@ module Checkoff
68
68
  date >= n_days_from_today
69
69
  end
70
70
 
71
+ # @param date_or_time [Date,Time,nil]
72
+ # @param num_days [Integer]
73
+ def greater_than_or_equal_to_n_days_from_now?(date_or_time, num_days)
74
+ return false if date_or_time.nil?
75
+
76
+ date_or_time >= n_days_from_now(num_days)
77
+ end
78
+
71
79
  # @param date_or_time [Date,Time,nil]
72
80
  # @param num_days [Integer]
73
81
  def less_than_n_days_ago?(date_or_time, num_days)
@@ -81,6 +89,14 @@ module Checkoff
81
89
  date < n_days_ago
82
90
  end
83
91
 
92
+ # @param date_or_time [Date,Time,nil]
93
+ # @param num_days [Integer]
94
+ def less_than_n_days_from_now?(date_or_time, num_days)
95
+ return false if date_or_time.nil?
96
+
97
+ date_or_time < n_days_from_now(num_days)
98
+ end
99
+
84
100
  # @param date_or_time [Date,Time,nil]
85
101
  def this_week?(date_or_time)
86
102
  return true if date_or_time.nil?
@@ -105,6 +121,29 @@ module Checkoff
105
121
  date_or_time.to_time < @now_getter.now
106
122
  end
107
123
 
124
+ # @param num_days [Integer]
125
+ #
126
+ # @return [Time]
127
+ def n_days_from_now(num_days)
128
+ (@now_getter.now + (num_days * 24 * 60 * 60))
129
+ end
130
+
131
+ # @param date_or_time [Date,Time,nil]
132
+ # @param beginning_num_days_from_now [Integer,nil]
133
+ # @param end_num_days_from_now [Integer,nil]
134
+ def between_relative_days?(date_or_time, beginning_num_days_from_now, end_num_days_from_now)
135
+ start_time = n_days_from_now(beginning_num_days_from_now || -99_999)
136
+ end_time = n_days_from_now(end_num_days_from_now || 99_999)
137
+
138
+ return false if date_or_time.nil?
139
+
140
+ if date_or_time.is_a?(Time)
141
+ date_or_time > start_time && date_or_time <= end_time
142
+ else
143
+ date_or_time > start_time.to_date && date_or_time <= end_time.to_date
144
+ end
145
+ end
146
+
108
147
  # @param date_or_time [Date,Time,nil]
109
148
  # @param period_name [Symbol]
110
149
  # @param args [Object]
@@ -112,11 +151,20 @@ module Checkoff
112
151
  # @sg-ignore
113
152
  return less_than_n_days_ago?(date_or_time, *args) if period_name == :less_than_n_days_ago
114
153
 
154
+ return less_than_n_days_from_now?(date_or_time, *args) if period_name == :less_than_n_days_from_now
155
+
156
+ if period_name == :greater_than_or_equal_to_n_days_from_now
157
+ return greater_than_or_equal_to_n_days_from_now?(date_or_time, *args)
158
+ end
159
+
115
160
  if period_name == :greater_than_or_equal_to_n_days_from_today
116
- return greater_than_or_equal_to_n_days_from_today?(date_or_time,
117
- *args)
161
+ return greater_than_or_equal_to_n_days_from_today?(date_or_time, *args)
118
162
  end
119
- raise "Teach me how to handle period [#{period_name.inspect}, #{args.join(', ')}]"
163
+
164
+ # @sg-ignore
165
+ return between_relative_days?(date_or_time, *args) if period_name == :between_relative_days
166
+
167
+ raise "Teach me how to handle period [#{period_name.inspect}, #{args.map(&:inspect).join(', ')}]"
120
168
  end
121
169
 
122
170
  # bundle exec ./time.rb
@@ -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.110.0'
6
+ VERSION = '0.112.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.110.0
4
+ version: 0.112.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-10-28 00:00:00.000000000 Z
11
+ date: 2023-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -134,7 +134,6 @@ files:
134
134
  - lib/checkoff/internal/config_loader.rb
135
135
  - lib/checkoff/internal/create-class.sh
136
136
  - lib/checkoff/internal/project_selector_evaluator.rb
137
- - lib/checkoff/internal/ready_between_relative.rb
138
137
  - lib/checkoff/internal/search_url.rb
139
138
  - lib/checkoff/internal/search_url/custom_field_param_converter.rb
140
139
  - lib/checkoff/internal/search_url/custom_field_variant.rb
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Checkoff
4
- module Internal
5
- # Determine whether a task is due within a relative date range
6
- class ReadyBetweenRelative
7
- # @param config [Hash<Symbol, Object>]
8
- # @param clients [Checkoff::Clients]
9
- # @param task_timing [Checkoff::Internal::TaskTiming]
10
- # @param tasks [Checkoff::Tasks]
11
- def initialize(config: Checkoff::Internal::ConfigLoader.load(:asana),
12
- clients: Checkoff::Clients.new(config: config),
13
- task_timing: ::Checkoff::Internal::TaskTiming.new,
14
- tasks: ::Checkoff::Tasks.new(config: config,
15
- client: clients.client))
16
- @task_timing = task_timing
17
- @tasks = tasks
18
- end
19
-
20
- # @param task [Asana::Resources::Task]
21
- # @param beginning_num_days_from_now [Integer]
22
- # @param end_num_days_from_now [Integer]
23
- # @param ignore_dependencies [Boolean]
24
- #
25
- # @return [Boolean]
26
- def ready_between_relative?(task,
27
- beginning_num_days_from_now,
28
- end_num_days_from_now,
29
- ignore_dependencies: false)
30
- beginning_n_days_from_now_time = (Time.now + (beginning_num_days_from_now * 24 * 60 * 60))
31
- end_n_days_from_now_time = (Time.now + (end_num_days_from_now * 24 * 60 * 60))
32
-
33
- # @type [Date, Time, nil]
34
- ready_date_or_time = @task_timing.date_or_time_field_by_name(task, :ready)
35
-
36
- return false if ready_date_or_time.nil?
37
-
38
- in_range = ready_in_range?(ready_date_or_time,
39
- beginning_n_days_from_now_time,
40
- end_n_days_from_now_time)
41
-
42
- return false unless in_range
43
-
44
- return false if !ignore_dependencies && @tasks.incomplete_dependencies?(task)
45
-
46
- true
47
- end
48
-
49
- private
50
-
51
- # @param ready_date_or_time [Date, Time]
52
- # @param start_time [Time]
53
- # @param end_time [Time]
54
- def ready_in_range?(ready_date_or_time, start_time, end_time)
55
- if ready_date_or_time.is_a?(Time)
56
- ready_date_or_time > start_time && ready_date_or_time <= end_time
57
- else
58
- ready_date_or_time > start_time.to_date && ready_date_or_time <= end_time.to_date
59
- end
60
- end
61
- end
62
- end
63
- end