checkoff 0.7.0 → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +120 -12
- data/.envrc +2 -0
- data/.git-hooks/pre_commit/circle_ci.rb +21 -0
- data/.gitignore +51 -1
- data/.overcommit.yml +32 -12
- data/.rubocop.yml +64 -168
- data/.yamllint.yml +8 -0
- data/CODE_OF_CONDUCT.md +120 -36
- data/DEVELOPMENT.md +28 -0
- data/Gemfile.lock +139 -0
- data/{LICENSE.txt → LICENSE} +7 -6
- data/Makefile +52 -18
- data/README.md +13 -2
- data/Rakefile +2 -9
- data/bin/bump +29 -0
- data/bin/checkoff +29 -0
- data/bin/overcommit +29 -0
- data/bin/rake +29 -0
- data/checkoff.gemspec +14 -6
- data/coverage/.last_run.json +2 -1
- data/docs/cookiecutter_input.json +13 -0
- data/exe/checkoff +1 -2
- data/fix.sh +334 -0
- data/lib/checkoff/cli.rb +97 -76
- data/lib/checkoff/config_loader.rb +22 -16
- data/lib/checkoff/projects.rb +35 -31
- data/lib/checkoff/sections.rb +98 -50
- data/lib/checkoff/subtasks.rb +14 -11
- data/lib/checkoff/tasks.rb +25 -16
- data/lib/checkoff/version.rb +2 -1
- data/lib/checkoff/workspaces.rb +10 -5
- data/metrics/bigfiles_high_water_mark +1 -1
- data/metrics/rubocop_high_water_mark +1 -1
- data/{lib/tasks/ci.rake → rakelib/citest.rake} +1 -1
- data/rakelib/clear_metrics.rake +17 -0
- data/{lib/tasks → rakelib}/default.rake +0 -0
- data/rakelib/gem_tasks.rake +3 -0
- data/{lib/tasks → rakelib}/localtest.rake +1 -1
- data/rakelib/overcommit.rake +6 -0
- data/rakelib/quality.rake +4 -0
- data/{lib/tasks → rakelib}/test.rake +0 -0
- data/rakelib/undercover.rake +8 -0
- data/requirements_dev.txt +2 -0
- metadata +110 -29
- data/.ruby-version +0 -1
- data/.travis.yml +0 -22
- data/lib/tasks/clear_metrics.rake +0 -8
- data/lib/tasks/feature.rake +0 -9
- data/lib/tasks/quality.rake +0 -9
- data/lib/tasks/spec.rake +0 -9
data/lib/checkoff/cli.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
require 'ostruct'
|
6
6
|
require 'dalli'
|
7
|
+
require 'gli'
|
7
8
|
require 'cache_method'
|
8
9
|
require_relative 'workspaces'
|
9
10
|
require_relative 'projects'
|
@@ -11,40 +12,44 @@ require_relative 'tasks'
|
|
11
12
|
require_relative 'sections'
|
12
13
|
|
13
14
|
module Checkoff
|
14
|
-
#
|
15
|
-
class
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
workspaces: Checkoff::Workspaces.new(config: config),
|
15
|
+
# CLI subcommand that shows tasks in JSON form
|
16
|
+
class ViewSubcommand
|
17
|
+
def initialize(workspace_name, project_name, section_name,
|
18
|
+
task_name,
|
19
|
+
config: Checkoff::ConfigLoader.load(:asana),
|
20
20
|
projects: Checkoff::Projects.new(config: config),
|
21
21
|
sections: Checkoff::Sections.new(config: config,
|
22
22
|
projects: projects),
|
23
|
-
tasks: Checkoff::Tasks.new(config: config
|
24
|
-
|
25
|
-
|
26
|
-
@
|
27
|
-
@
|
23
|
+
tasks: Checkoff::Tasks.new(config: config,
|
24
|
+
sections: sections),
|
25
|
+
stderr: $stderr)
|
26
|
+
@workspace_name = workspace_name
|
27
|
+
@stderr = stderr
|
28
|
+
validate_and_assign_project_name(project_name)
|
29
|
+
@section_name = section_name
|
30
|
+
@task_name = task_name
|
28
31
|
@sections = sections
|
29
32
|
@tasks = tasks
|
30
|
-
@kernel = kernel
|
31
|
-
@stderr = stderr
|
32
33
|
end
|
33
34
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
task_out[:due] = task.due_at
|
35
|
+
def run
|
36
|
+
if section_name.nil?
|
37
|
+
run_on_project(workspace_name, project_name)
|
38
|
+
elsif task_name.nil?
|
39
|
+
run_on_section(workspace_name, project_name, section_name)
|
40
|
+
else
|
41
|
+
run_on_task(workspace_name, project_name, section_name, task_name)
|
42
42
|
end
|
43
|
-
task_out
|
44
43
|
end
|
45
44
|
|
46
|
-
|
47
|
-
|
45
|
+
private
|
46
|
+
|
47
|
+
def validate_and_assign_project_name(project_name)
|
48
|
+
@project_name = if project_name.start_with? ':'
|
49
|
+
project_name[1..].to_sym
|
50
|
+
else
|
51
|
+
project_name
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
def run_on_project(workspace, project)
|
@@ -62,72 +67,88 @@ module Checkoff
|
|
62
67
|
tasks_to_hash(tasks).to_json
|
63
68
|
end
|
64
69
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
70
|
+
def run_on_task(workspace, project, section, task_name)
|
71
|
+
section = nil if section == ''
|
72
|
+
task = tasks.task(workspace, project, task_name, section_name: section)
|
73
|
+
task_to_hash(task).to_json
|
69
74
|
end
|
70
75
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
+
def task_to_hash(task)
|
77
|
+
task_out = {
|
78
|
+
name: task.name,
|
79
|
+
}
|
80
|
+
if task.due_on
|
81
|
+
task_out[:due] = task.due_on
|
82
|
+
elsif task.due_at
|
83
|
+
task_out[:due] = task.due_at
|
84
|
+
end
|
85
|
+
task_out
|
76
86
|
end
|
77
87
|
|
78
|
-
def
|
79
|
-
|
80
|
-
subargs.project = args[2]
|
81
|
-
subargs.section = args[3]
|
88
|
+
def tasks_to_hash(tasks)
|
89
|
+
tasks.map { |task| task_to_hash(task) }
|
82
90
|
end
|
83
91
|
|
84
|
-
|
85
|
-
|
86
|
-
subargs.task_name = args[2]
|
87
|
-
end
|
92
|
+
attr_reader :workspace_name, :project_name, :section_name, :task_name, :sections, :tasks, :stderr
|
93
|
+
end
|
88
94
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
100
|
-
[mode, subargs]
|
95
|
+
# CLI subcommand that creates a task
|
96
|
+
class QuickaddSubcommand
|
97
|
+
def initialize(workspace_name, task_name,
|
98
|
+
config: Checkoff::ConfigLoader.load(:asana),
|
99
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
100
|
+
tasks: Checkoff::Tasks.new(config: config))
|
101
|
+
@workspace_name = workspace_name
|
102
|
+
@task_name = task_name
|
103
|
+
@workspaces = workspaces
|
104
|
+
@tasks = tasks
|
101
105
|
end
|
102
106
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
stderr.puts
|
108
|
-
stderr.puts "'project' can be set to a project name, or :my_tasks, " \
|
109
|
-
":my_tasks_upcoming, :my_tasks_new, or :my_tasks_today"
|
107
|
+
def run
|
108
|
+
workspace = @workspaces.workspace_by_name(workspace_name)
|
109
|
+
@tasks.add_task(task_name,
|
110
|
+
workspace_gid: workspace.gid)
|
110
111
|
end
|
111
112
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
113
|
+
private
|
114
|
+
|
115
|
+
attr_reader :workspace_name, :task_name
|
116
|
+
end
|
117
|
+
|
118
|
+
# Provide ability for CLI to pull Asana items
|
119
|
+
class CheckoffGLIApp
|
120
|
+
extend GLI::App
|
121
|
+
|
122
|
+
program_desc 'Command-line client for Asana (unofficial)'
|
123
|
+
|
124
|
+
subcommand_option_handling :normal
|
125
|
+
arguments :strict
|
126
|
+
|
127
|
+
desc 'Add a short task to Asana'
|
128
|
+
arg 'workspace'
|
129
|
+
arg 'task_name'
|
130
|
+
command :quickadd do |c|
|
131
|
+
c.action do |_global_options, _options, args|
|
132
|
+
workspace_name = args.fetch(0)
|
133
|
+
task_name = args.fetch(1)
|
134
|
+
|
135
|
+
QuickaddSubcommand.new(workspace_name, task_name).run
|
118
136
|
end
|
119
137
|
end
|
120
138
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
139
|
+
desc 'Output representation of Asana tasks'
|
140
|
+
arg 'workspace'
|
141
|
+
arg 'project'
|
142
|
+
arg 'section', :optional
|
143
|
+
arg 'task_name', :optional
|
144
|
+
command :view do |c|
|
145
|
+
c.action do |_global_options, _options, args|
|
146
|
+
workspace_name = args.fetch(0)
|
147
|
+
project_name = args.fetch(1)
|
148
|
+
section_name = args[2]
|
149
|
+
task_name = args[3]
|
150
|
+
|
151
|
+
puts ViewSubcommand.new(workspace_name, project_name, section_name, task_name).run
|
131
152
|
end
|
132
153
|
end
|
133
154
|
end
|
@@ -13,10 +13,6 @@ module Checkoff
|
|
13
13
|
@yaml_filename = yaml_filename
|
14
14
|
end
|
15
15
|
|
16
|
-
def envvar_name(key)
|
17
|
-
"#{@envvar_prefix}__#{key.upcase}"
|
18
|
-
end
|
19
|
-
|
20
16
|
def [](key)
|
21
17
|
config_value = @config[key]
|
22
18
|
return config_value unless config_value.nil?
|
@@ -31,25 +27,35 @@ module Checkoff
|
|
31
27
|
raise KeyError,
|
32
28
|
"Please configure either the #{key} key in #{@yaml_filename} or set #{envvar_name(key)}"
|
33
29
|
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def envvar_name(key)
|
34
|
+
"#{@envvar_prefix}__#{key.upcase}"
|
35
|
+
end
|
34
36
|
end
|
35
37
|
|
36
38
|
# Load configuration file
|
37
39
|
class ConfigLoader
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
class << self
|
41
|
+
def load(sym)
|
42
|
+
yaml_result = load_yaml_file(sym)
|
43
|
+
EnvFallbackConfigLoader.new(yaml_result, sym, yaml_filename(sym))
|
44
|
+
end
|
42
45
|
|
43
|
-
|
44
|
-
filename = yaml_filename(sym)
|
45
|
-
return {} unless File.exist?(filename)
|
46
|
+
private
|
46
47
|
|
47
|
-
|
48
|
-
|
48
|
+
def load_yaml_file(sym)
|
49
|
+
filename = yaml_filename(sym)
|
50
|
+
return {} unless File.exist?(filename)
|
51
|
+
|
52
|
+
YAML.load_file(filename).with_indifferent_access
|
53
|
+
end
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
def yaml_filename(sym)
|
56
|
+
file = "#{sym}.yml"
|
57
|
+
File.expand_path("~/.#{file}")
|
58
|
+
end
|
53
59
|
end
|
54
60
|
end
|
55
61
|
end
|
data/lib/checkoff/projects.rb
CHANGED
@@ -22,8 +22,6 @@ module Checkoff
|
|
22
22
|
LONG_CACHE_TIME = MINUTE * 15
|
23
23
|
SHORT_CACHE_TIME = MINUTE * 5
|
24
24
|
|
25
|
-
# XXX: Move low-level functions private
|
26
|
-
|
27
25
|
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
28
26
|
asana_client: Asana::Client,
|
29
27
|
workspaces: Checkoff::Workspaces.new(config: config))
|
@@ -32,30 +30,12 @@ module Checkoff
|
|
32
30
|
@workspaces = workspaces
|
33
31
|
end
|
34
32
|
|
33
|
+
# Returns Asana Ruby API Client object
|
35
34
|
def client
|
36
35
|
@workspaces.client
|
37
36
|
end
|
38
37
|
|
39
|
-
|
40
|
-
client.projects
|
41
|
-
end
|
42
|
-
cache_method :projects, LONG_CACHE_TIME
|
43
|
-
|
44
|
-
def projects_by_workspace_name(workspace_name)
|
45
|
-
workspace = @workspaces.workspace_by_name(workspace_name)
|
46
|
-
raise "Could not find workspace named #{workspace_name}" unless workspace
|
47
|
-
|
48
|
-
projects.find_by_workspace(workspace: workspace.gid)
|
49
|
-
end
|
50
|
-
|
51
|
-
def my_tasks(workspace_name)
|
52
|
-
my_tasks = @config.fetch(:my_tasks)
|
53
|
-
gid = my_tasks[workspace_name] unless my_tasks.nil?
|
54
|
-
raise "Please define [:my_tasks][#{workspace_name}] in config file" if my_tasks.nil? || gid.nil?
|
55
|
-
|
56
|
-
projects.find_by_id(gid)
|
57
|
-
end
|
58
|
-
|
38
|
+
# pulls an Asana API project class given a name
|
59
39
|
def project(workspace_name, project_name)
|
60
40
|
if project_name.is_a?(Symbol) && project_name.to_s.start_with?('my_tasks')
|
61
41
|
my_tasks(workspace_name)
|
@@ -68,10 +48,43 @@ module Checkoff
|
|
68
48
|
end
|
69
49
|
cache_method :project, LONG_CACHE_TIME
|
70
50
|
|
51
|
+
# find uncompleted tasks in a list
|
71
52
|
def active_tasks(tasks)
|
72
53
|
tasks.select { |task| task.completed_at.nil? }
|
73
54
|
end
|
74
55
|
|
56
|
+
# pull task objects from a named project
|
57
|
+
def tasks_from_project(project, only_uncompleted: true, extra_fields: [])
|
58
|
+
options = task_options
|
59
|
+
options[:completed_since] = '9999-12-01' if only_uncompleted
|
60
|
+
options[:project] = project.gid
|
61
|
+
options[:options][:fields] += extra_fields
|
62
|
+
client.tasks.find_all(**options).to_a
|
63
|
+
end
|
64
|
+
cache_method :tasks_from_project, SHORT_CACHE_TIME
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def projects
|
69
|
+
client.projects
|
70
|
+
end
|
71
|
+
cache_method :projects, LONG_CACHE_TIME
|
72
|
+
|
73
|
+
def projects_by_workspace_name(workspace_name)
|
74
|
+
workspace = @workspaces.workspace_by_name(workspace_name)
|
75
|
+
raise "Could not find workspace named #{workspace_name}" unless workspace
|
76
|
+
|
77
|
+
projects.find_by_workspace(workspace: workspace.gid)
|
78
|
+
end
|
79
|
+
|
80
|
+
def my_tasks(workspace_name)
|
81
|
+
workspace = @workspaces.workspace_by_name(workspace_name)
|
82
|
+
result = client.user_task_lists.get_user_task_list_for_user(user_gid: 'me',
|
83
|
+
workspace: workspace.gid)
|
84
|
+
gid = result.gid
|
85
|
+
projects.find_by_id(gid)
|
86
|
+
end
|
87
|
+
|
75
88
|
def task_options
|
76
89
|
{
|
77
90
|
per_page: 100,
|
@@ -81,14 +94,5 @@ module Checkoff
|
|
81
94
|
},
|
82
95
|
}
|
83
96
|
end
|
84
|
-
|
85
|
-
def tasks_from_project(project, only_uncompleted: true, extra_fields: [])
|
86
|
-
options = task_options
|
87
|
-
options[:completed_since] = '9999-12-01' if only_uncompleted
|
88
|
-
options[:project] = project.gid
|
89
|
-
options[:options][:fields] += extra_fields
|
90
|
-
client.tasks.find_all(**options).to_a
|
91
|
-
end
|
92
|
-
cache_method :tasks_from_project, SHORT_CACHE_TIME
|
93
97
|
end
|
94
98
|
end
|
data/lib/checkoff/sections.rb
CHANGED
@@ -4,6 +4,7 @@ require 'forwardable'
|
|
4
4
|
|
5
5
|
module Checkoff
|
6
6
|
# Query different sections of Asana projects
|
7
|
+
# rubocop:disable Metrics/ClassLength
|
7
8
|
class Sections
|
8
9
|
MINUTE = 60
|
9
10
|
LONG_CACHE_TIME = MINUTE * 15
|
@@ -11,15 +12,82 @@ module Checkoff
|
|
11
12
|
|
12
13
|
extend Forwardable
|
13
14
|
|
14
|
-
attr_reader :projects, :time
|
15
|
+
attr_reader :projects, :workspaces, :time
|
15
16
|
|
16
17
|
def initialize(config: Checkoff::ConfigLoader.load(:asana),
|
17
18
|
projects: Checkoff::Projects.new(config: config),
|
19
|
+
workspaces: Checkoff::Workspaces.new(config: config),
|
18
20
|
time: Time)
|
19
21
|
@projects = projects
|
22
|
+
@workspaces = workspaces
|
20
23
|
@time = time
|
21
24
|
end
|
22
25
|
|
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)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Given a workspace name and project name, then provide a Hash of
|
45
|
+
# tasks with section name -> task list of the uncompleted tasks
|
46
|
+
def tasks_by_section(workspace_name, project_name)
|
47
|
+
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
|
54
|
+
end
|
55
|
+
cache_method :tasks_by_section, SHORT_CACHE_TIME
|
56
|
+
|
57
|
+
# XXX: Rename to section_tasks
|
58
|
+
#
|
59
|
+
# 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, [])
|
62
|
+
end
|
63
|
+
cache_method :tasks, SHORT_CACHE_TIME
|
64
|
+
|
65
|
+
# Pulls just names of tasks from a given section.
|
66
|
+
def section_task_names(workspace_name, project_name, section_name)
|
67
|
+
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
|
+
tasks.map(&:name)
|
75
|
+
end
|
76
|
+
cache_method :section_task_names, SHORT_CACHE_TIME
|
77
|
+
|
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
|
+
private
|
90
|
+
|
23
91
|
def_delegators :@projects, :client
|
24
92
|
|
25
93
|
def file_task_by_section(by_section, task, project_gid)
|
@@ -32,19 +100,10 @@ module Checkoff
|
|
32
100
|
by_section[current_section] << task
|
33
101
|
end
|
34
102
|
|
35
|
-
def
|
36
|
-
by_section = {}
|
37
|
-
tasks.each do |task|
|
38
|
-
file_task_by_section(by_section, task, project_gid)
|
39
|
-
end
|
40
|
-
by_section
|
41
|
-
end
|
42
|
-
cache_method :by_section, LONG_CACHE_TIME
|
43
|
-
|
44
|
-
def tasks_by_section_for_project(project)
|
103
|
+
def legacy_tasks_by_section_for_project(project)
|
45
104
|
raw_tasks = projects.tasks_from_project(project)
|
46
105
|
active_tasks = projects.active_tasks(raw_tasks)
|
47
|
-
|
106
|
+
legacy_by_section(active_tasks)
|
48
107
|
end
|
49
108
|
|
50
109
|
def legacy_file_task_by_section(current_section, by_section, task)
|
@@ -68,12 +127,12 @@ module Checkoff
|
|
68
127
|
by_section
|
69
128
|
end
|
70
129
|
|
71
|
-
def
|
72
|
-
|
130
|
+
def legacy_tasks_by_section_for_project_and_assignee_status(project,
|
131
|
+
assignee_status)
|
73
132
|
raw_tasks = projects.tasks_from_project(project)
|
74
133
|
by_assignee_status =
|
75
134
|
projects.active_tasks(raw_tasks)
|
76
|
-
|
135
|
+
.group_by(&:assignee_status)
|
77
136
|
active_tasks = by_assignee_status[assignee_status]
|
78
137
|
legacy_by_section(active_tasks)
|
79
138
|
end
|
@@ -87,49 +146,37 @@ module Checkoff
|
|
87
146
|
project
|
88
147
|
end
|
89
148
|
|
90
|
-
def
|
91
|
-
|
92
|
-
case project_name
|
93
|
-
when :my_tasks_new
|
94
|
-
tasks_by_section_for_project_and_assignee_status(project, 'inbox')
|
95
|
-
when :my_tasks_today
|
96
|
-
tasks_by_section_for_project_and_assignee_status(project, 'today')
|
97
|
-
when :my_tasks_upcoming
|
98
|
-
tasks_by_section_for_project_and_assignee_status(project, 'upcoming')
|
99
|
-
else
|
100
|
-
tasks_by_section_for_project(project)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
cache_method :tasks_by_section, SHORT_CACHE_TIME
|
149
|
+
def verify_legacy_user_task_list!(workspace_name)
|
150
|
+
return unless user_task_list_migrated_to_real_sections?(workspace_name)
|
104
151
|
|
105
|
-
|
106
|
-
def tasks(workspace_name, project_name, section_name)
|
107
|
-
tasks_by_section(workspace_name, project_name)[section_name]
|
152
|
+
raise NotImplementedError, 'Section-based user task lists not yet supported'
|
108
153
|
end
|
109
|
-
cache_method :tasks, SHORT_CACHE_TIME
|
110
154
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
raise "Could not find task names for #{desc}. " \
|
117
|
-
"Valid sections: #{by_section.keys}"
|
118
|
-
end
|
119
|
-
tasks.map(&:name)
|
120
|
-
end
|
121
|
-
cache_method :section_task_names, SHORT_CACHE_TIME
|
155
|
+
ASSIGNEE_STATUS_BY_PROJECT_NAME = {
|
156
|
+
my_tasks_new: 'inbox',
|
157
|
+
my_tasks_today: 'today',
|
158
|
+
my_tasks_upcoming: 'upcoming',
|
159
|
+
}.freeze
|
122
160
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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)
|
128
167
|
else
|
129
|
-
|
168
|
+
legacy_tasks_by_section_for_project_and_assignee_status(project,
|
169
|
+
ASSIGNEE_STATUS_BY_PROJECT_NAME.fetch(project_name))
|
130
170
|
end
|
131
171
|
end
|
132
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
|
179
|
+
|
133
180
|
def project_task_names(workspace_name, project_name)
|
134
181
|
by_section = tasks_by_section(workspace_name, project_name)
|
135
182
|
by_section.flat_map do |section_name, tasks|
|
@@ -143,4 +190,5 @@ module Checkoff
|
|
143
190
|
end
|
144
191
|
cache_method :project_task_names, SHORT_CACHE_TIME
|
145
192
|
end
|
193
|
+
# rubocop:enable Metrics/ClassLength
|
146
194
|
end
|