researchable-freedcamp-api 0.1.5 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/researchable/freedcamp_api/constants.rb +33 -0
- data/lib/researchable/freedcamp_api/endpoint.rb +1 -1
- data/lib/researchable/freedcamp_api/get_user.rb +20 -0
- data/lib/researchable/freedcamp_api/list_discussions.rb +28 -0
- data/lib/researchable/freedcamp_api/list_lists.rb +37 -0
- data/lib/researchable/freedcamp_api/list_milestones.rb +34 -1
- data/lib/researchable/freedcamp_api/list_projects.rb +33 -1
- data/lib/researchable/freedcamp_api/list_task_lists.rb +40 -0
- data/lib/researchable/freedcamp_api/list_tasks.rb +19 -5
- data/lib/researchable/freedcamp_api/sessions/signed_session.rb +14 -25
- data/lib/researchable/freedcamp_api/structs/task.rb +3 -0
- data/lib/researchable/freedcamp_api/version.rb +1 -1
- data/lib/researchable/freedcamp_api.rb +11 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77bb6dfffc6fce9c8d4a7636182781955b49b11f1507d0d50dc8974eb88ba7fa
|
4
|
+
data.tar.gz: 7a0fbb253039d096f2bc282e5363ba53f433132b02dec6f555891cdc9067ab4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34ff2ec76464026a977b6dedb4cbf5b99b8f411ce5fcd504cb89c4de5d5ddbc1017210dbd93cdbe6a87d7340f897c9d812031f8026fd2fcd2ceb181c990363ce
|
7
|
+
data.tar.gz: '09bcc82ef7455a191b7cc20dc8ee5fba4c0acac1285e4ff918606466de3dad4595d167610ca52588d893043d53dd64e2d71a2e17611952c0a4ed1eefd6f1e25c'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Researchable
|
5
|
+
module FreedcampApi
|
6
|
+
APP_WALL = 1
|
7
|
+
APP_TODOS = 2
|
8
|
+
APP_DISCUSSIONS = 3
|
9
|
+
APP_MILESTONES = 4
|
10
|
+
APP_TIME = 5
|
11
|
+
APP_FILES = 6
|
12
|
+
APP_INVOICES = 7
|
13
|
+
APP_BUGTRACKER = 13
|
14
|
+
APP_WIKI = 14
|
15
|
+
APP_CRM = 16
|
16
|
+
APP_PASSMAN = 17
|
17
|
+
APP_TASKY = 18
|
18
|
+
APP_CALENDAR = 19
|
19
|
+
APP_INVOICESPLUS = 20
|
20
|
+
MODULE_GDOCS = 21
|
21
|
+
MODULE_PROJ_CLONING = 22
|
22
|
+
|
23
|
+
PROGRESS_NO_PROGRESS = 0
|
24
|
+
PROGRESS_IN_PROGRESS = 2
|
25
|
+
PROGRESS_COMPLETED = 1
|
26
|
+
|
27
|
+
STATUS_NOT_STARTED = 0
|
28
|
+
STATUS_COMPLETED = 1
|
29
|
+
STATUS_IN_PROGRESS = 2
|
30
|
+
STATUS_INVALID = 3
|
31
|
+
STATUS_REVIEW = 4
|
32
|
+
end
|
33
|
+
end
|
@@ -23,7 +23,7 @@ module Researchable
|
|
23
23
|
|
24
24
|
while has_more
|
25
25
|
temp = yield limit, offset
|
26
|
-
has_more = T.let(temp.dig('data', 'meta', 'has_more') ==
|
26
|
+
has_more = T.let(temp.dig('data', 'meta', 'has_more') == true, T::Boolean)
|
27
27
|
result += temp['data'][keyword]
|
28
28
|
offset += limit
|
29
29
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# typed: false
|
2
|
+
module Researchable
|
3
|
+
module FreedcampApi
|
4
|
+
class GetUser < Endpoint
|
5
|
+
string :user_id, default: 'current'
|
6
|
+
# @api private
|
7
|
+
def execute
|
8
|
+
get_user(user_id)
|
9
|
+
end
|
10
|
+
|
11
|
+
#sig do
|
12
|
+
#params().returns(
|
13
|
+
#)
|
14
|
+
#end
|
15
|
+
def get_user(task_id)
|
16
|
+
session.get("/users/#{task_id}")['data']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# typed: false
|
2
|
+
module Researchable
|
3
|
+
module FreedcampApi
|
4
|
+
class ListDiscussions < Endpoint
|
5
|
+
integer :discussion_id, default: nil
|
6
|
+
integer :project_id, default: nil
|
7
|
+
|
8
|
+
def execute
|
9
|
+
list_discussions(discussion_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
# sig do
|
13
|
+
# params(
|
14
|
+
# task_id: T.nilable(Integer)
|
15
|
+
# ).returns(
|
16
|
+
# T::Array[Researchable::FreedcampApi::Structs::Task]
|
17
|
+
# )
|
18
|
+
# end
|
19
|
+
def list_discussions(discussion_id)
|
20
|
+
discussion_query = discussion_id ? "/#{discussion_id}" : '/'
|
21
|
+
project_query = project_id ? "?project_id=#{project_id}" : ''
|
22
|
+
url = "/discussions#{discussion_query}
|
23
|
+
#{project_query}"
|
24
|
+
session.get(url)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# typed: false
|
2
|
+
module Researchable
|
3
|
+
module FreedcampApi
|
4
|
+
class ListLists < Endpoint
|
5
|
+
string :project_id, default: nil
|
6
|
+
integer :app_id, default: Researchable::FreedcampApi::APP_TODOS
|
7
|
+
# @api private
|
8
|
+
def execute
|
9
|
+
check_app_id(app_id)
|
10
|
+
list_lists(app_id, project_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def check_app_id(app_id)
|
16
|
+
return if allowed_apps.include? app_id
|
17
|
+
|
18
|
+
raise "app_id not allowed: #{app_id} not in #{allowed_apps}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def allowed_apps
|
22
|
+
[APP_TODOS, APP_FILES, APP_DISCUSSIONS, APP_WIKI, APP_PASSMAN]
|
23
|
+
end
|
24
|
+
|
25
|
+
def list_lists(app_id, project_id)
|
26
|
+
project_id_query = project_id ? "&project_id=#{project_id}" : ''
|
27
|
+
fetch_all('lists') do |limit, offset|
|
28
|
+
url = "/lists/#{app_id}
|
29
|
+
?limit=#{limit}
|
30
|
+
&offset=#{offset}
|
31
|
+
#{project_id_query}"
|
32
|
+
session.get(url)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1 +1,34 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: false
|
2
|
+
module Researchable
|
3
|
+
module FreedcampApi
|
4
|
+
class ListMilestones < Endpoint
|
5
|
+
integer :milestone_id, default: nil
|
6
|
+
integer :project_id, default: nil
|
7
|
+
integer :f_cf, default: 1
|
8
|
+
|
9
|
+
def execute
|
10
|
+
list_milestones(milestone_id)
|
11
|
+
end
|
12
|
+
|
13
|
+
# sig do
|
14
|
+
# params(
|
15
|
+
# task_id: T.nilable(Integer)
|
16
|
+
# ).returns(
|
17
|
+
# T::Array[Researchable::FreedcampApi::Structs::Task]
|
18
|
+
# )
|
19
|
+
# end
|
20
|
+
def list_milestones(milestone_id)
|
21
|
+
milestone_query = milestone_id ? "/#{milestone_id}" : '/'
|
22
|
+
project_query = project_id ? "&project_id=#{project_id}" : ''
|
23
|
+
custom_fields_query = f_cf.nil? ? '' : "&f_cf=#{f_cf}"
|
24
|
+
fetch_all('milestones') do |limit, offset|
|
25
|
+
url = "/milestones#{milestone_query}?limit=#{limit}
|
26
|
+
#{project_query}
|
27
|
+
#{custom_fields_query}
|
28
|
+
&offset=#{offset}"
|
29
|
+
session.get(url)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1 +1,33 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: false
|
2
|
+
module Researchable
|
3
|
+
module FreedcampApi
|
4
|
+
class ListProjects < Endpoint
|
5
|
+
integer :project_id, default: nil
|
6
|
+
integer :f_with_archived, default: 1
|
7
|
+
|
8
|
+
# Accepts "active", "archived", "all" values. Omitting is equal to "active".
|
9
|
+
string :lists_status, default: 'active'
|
10
|
+
integer :f_cf, default: 1
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
def execute
|
14
|
+
list_projects(project_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
# sig do
|
18
|
+
# params(
|
19
|
+
# project_id: T.nilable(Integer)
|
20
|
+
# ).returns(
|
21
|
+
# T::Array[Researchable::FreedcampApi::Structs::Task]
|
22
|
+
# )
|
23
|
+
# end
|
24
|
+
def list_projects(project_id)
|
25
|
+
project_query = project_id ? "/#{project_id}" : '/'
|
26
|
+
fetch_all('projects') do |limit, offset|
|
27
|
+
session.get("/projects#{project_query}?limit=#{limit}
|
28
|
+
&offset=#{offset}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# typed: false
|
2
|
+
module Researchable
|
3
|
+
module FreedcampApi
|
4
|
+
class ListTasks < Endpoint
|
5
|
+
integer :project_id, default: nil
|
6
|
+
integer :f_with_archived, default: 1
|
7
|
+
|
8
|
+
# Accepts "active", "archived", "all" values. Omitting is equal to "active".
|
9
|
+
string :lists_status, default: 'active'
|
10
|
+
string :assigned_to_id, default: nil
|
11
|
+
integer :f_cf, default: 1
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
def execute
|
15
|
+
list_tasks(task_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
sig do
|
19
|
+
params(
|
20
|
+
task_id: T.nilable(Integer)
|
21
|
+
).returns(
|
22
|
+
T::Array[Researchable::FreedcampApi::Structs::Task]
|
23
|
+
)
|
24
|
+
end
|
25
|
+
def list_tasks(task_id)
|
26
|
+
task_query = task_id ? "/#{task_id}" : '/'
|
27
|
+
assigned_to_id_query = assigned_to_id ? "&assigned_to_id[]=#{assigned_to_id}" : ''
|
28
|
+
fetch_all('tasks') do |limit, offset|
|
29
|
+
url = "/tasks#{task_query}?limit=#{limit}
|
30
|
+
&offset=#{offset}
|
31
|
+
#{assigned_to_id_query}
|
32
|
+
&f_with_archived=#{f_with_archived}
|
33
|
+
&f_cf=#{f_cf}
|
34
|
+
&lists_status=#{lists_status}"
|
35
|
+
session.get(url)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -3,11 +3,14 @@ module Researchable
|
|
3
3
|
module FreedcampApi
|
4
4
|
class ListTasks < Endpoint
|
5
5
|
integer :task_id, default: nil
|
6
|
-
integer :f_with_archived, default:
|
6
|
+
integer :f_with_archived, default: 0
|
7
|
+
array :status, default: []
|
7
8
|
|
8
9
|
# Accepts "active", "archived", "all" values. Omitting is equal to "active".
|
9
10
|
string :lists_status, default: 'active'
|
11
|
+
string :assigned_to_id, default: nil
|
10
12
|
integer :f_cf, default: 1
|
13
|
+
boolean :include_subtasks, default: true
|
11
14
|
|
12
15
|
# @api private
|
13
16
|
def execute
|
@@ -23,13 +26,24 @@ module Researchable
|
|
23
26
|
end
|
24
27
|
def list_tasks(task_id)
|
25
28
|
task_query = task_id ? "/#{task_id}" : '/'
|
26
|
-
|
27
|
-
|
29
|
+
assigned_to_id_query = assigned_to_id ? "&assigned_to_id[]=#{assigned_to_id}" : ''
|
30
|
+
f_with_archived_query = f_with_archived ? "&f_with_archived=#{f_with_archived}" : ''
|
31
|
+
status_query = status.reduce('') { |tot, cur| "#{tot}&status[]=#{cur}" }
|
32
|
+
# status[]=&status[]=2
|
33
|
+
tasks = fetch_all('tasks') do |limit, offset|
|
34
|
+
url = "/tasks#{task_query}?limit=#{limit}
|
28
35
|
&offset=#{offset}
|
29
|
-
|
36
|
+
#{assigned_to_id_query}
|
37
|
+
#{f_with_archived_query}
|
38
|
+
#{status_query}
|
30
39
|
&f_cf=#{f_cf}
|
31
|
-
&lists_status=#{lists_status}"
|
40
|
+
&lists_status=#{lists_status}"
|
41
|
+
session.get(url)
|
32
42
|
end
|
43
|
+
|
44
|
+
return tasks if include_subtasks
|
45
|
+
|
46
|
+
tasks.select { |task| task['h_top_id'].blank? }
|
33
47
|
end
|
34
48
|
end
|
35
49
|
end
|
@@ -23,16 +23,13 @@ module Researchable
|
|
23
23
|
sig { returns(String) }
|
24
24
|
attr_reader :secret_key
|
25
25
|
|
26
|
-
sig { returns(T::Boolean) }
|
27
|
-
attr_reader :use_cache
|
28
|
-
|
29
26
|
# rubocop:enable Style/AccessorGrouping
|
30
27
|
|
31
|
-
sig { params(public_key: String, secret_key: String
|
32
|
-
def initialize(public_key: ENV['PUBLIC_KEY'], secret_key: ENV['SECRET_KEY']
|
28
|
+
sig { params(public_key: String, secret_key: String).void }
|
29
|
+
def initialize(public_key: ENV['PUBLIC_KEY'], secret_key: ENV['SECRET_KEY'])
|
33
30
|
@public_key = public_key
|
34
31
|
@secret_key = secret_key
|
35
|
-
@
|
32
|
+
@debug = false
|
36
33
|
end
|
37
34
|
|
38
35
|
sig { override.params(path: String).returns(T::Hash[T.untyped, T.untyped]) }
|
@@ -68,32 +65,21 @@ module Researchable
|
|
68
65
|
).returns(T::Hash[T.untyped, T.untyped])
|
69
66
|
end
|
70
67
|
def call_url(path, method, data = {})
|
71
|
-
|
72
|
-
content = if data == {} && File.exist?(cache_url) && @use_cache
|
73
|
-
render_cache(cache_url)
|
74
|
-
else
|
75
|
-
render_call(path, method, data, cache_url)
|
76
|
-
end
|
68
|
+
content = render_call(path, method, data)
|
77
69
|
|
78
70
|
content = JSON.parse(content) if content
|
79
71
|
content
|
80
72
|
end
|
81
73
|
|
82
|
-
def
|
83
|
-
file = File.open(cache_url)
|
84
|
-
content = file.read
|
85
|
-
end
|
86
|
-
|
87
|
-
def render_call(path, method, data, cache_url)
|
74
|
+
def render_call(path, method, data)
|
88
75
|
signature = generate_signature
|
89
76
|
url = make_url(path, signature)
|
90
77
|
data = serialize_data(data)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
content
|
78
|
+
puts url if @debug
|
79
|
+
HTTParty.send(method,
|
80
|
+
url,
|
81
|
+
body: data,
|
82
|
+
headers: HEADERS).body
|
97
83
|
end
|
98
84
|
|
99
85
|
def serialize_data(data = {})
|
@@ -107,7 +93,10 @@ module Researchable
|
|
107
93
|
def make_url(path, signature)
|
108
94
|
result = BASE + path
|
109
95
|
sep = result.include?('?') ? '&' : '?'
|
110
|
-
result
|
96
|
+
result += "#{sep}api_key=#{signature.api_key}×tamp=#{signature.timestamp}&hash=#{signature.calculated_hash}"
|
97
|
+
result = result.gsub(/\n\s+/, '')
|
98
|
+
puts result if @debug
|
99
|
+
result
|
111
100
|
end
|
112
101
|
|
113
102
|
sig { returns(Signature) }
|
@@ -42,6 +42,9 @@ module Researchable
|
|
42
42
|
|
43
43
|
const :status, T.nilable(Integer)
|
44
44
|
const :status_title, T.nilable(String)
|
45
|
+
|
46
|
+
# Shows the top parent task id (so is equal to h_parent_id for subtasks with h_level=1, and differs for subtasks with h_level > 1). Is an empty string for top-level tasks.
|
47
|
+
const :h_top_id, T.nilable(String)
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
@@ -3,14 +3,25 @@
|
|
3
3
|
|
4
4
|
require 'active_interaction'
|
5
5
|
require_relative 'freedcamp_api/version'
|
6
|
+
require_relative 'freedcamp_api/constants'
|
6
7
|
require_relative 'freedcamp_api/structs'
|
7
8
|
require_relative 'freedcamp_api/sessions'
|
8
9
|
require_relative 'freedcamp_api/endpoint'
|
9
10
|
|
11
|
+
require_relative 'freedcamp_api/list_projects'
|
12
|
+
require_relative 'freedcamp_api/list_discussions'
|
13
|
+
|
14
|
+
|
10
15
|
require_relative 'freedcamp_api/list_tasks'
|
11
16
|
require_relative 'freedcamp_api/update_task'
|
12
17
|
require_relative 'freedcamp_api/create_task'
|
13
18
|
|
19
|
+
require_relative 'freedcamp_api/get_user'
|
20
|
+
|
21
|
+
require_relative 'freedcamp_api/list_lists'
|
22
|
+
|
23
|
+
require_relative 'freedcamp_api/list_milestones'
|
24
|
+
|
14
25
|
require_relative 'freedcamp_api/create_comment'
|
15
26
|
|
16
27
|
module Researchable
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: researchable-freedcamp-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Blaauw
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_interaction
|
@@ -126,11 +126,16 @@ files:
|
|
126
126
|
- bin/setup
|
127
127
|
- lib/researchable-freedcamp-api.rb
|
128
128
|
- lib/researchable/freedcamp_api.rb
|
129
|
+
- lib/researchable/freedcamp_api/constants.rb
|
129
130
|
- lib/researchable/freedcamp_api/create_comment.rb
|
130
131
|
- lib/researchable/freedcamp_api/create_task.rb
|
131
132
|
- lib/researchable/freedcamp_api/endpoint.rb
|
133
|
+
- lib/researchable/freedcamp_api/get_user.rb
|
134
|
+
- lib/researchable/freedcamp_api/list_discussions.rb
|
135
|
+
- lib/researchable/freedcamp_api/list_lists.rb
|
132
136
|
- lib/researchable/freedcamp_api/list_milestones.rb
|
133
137
|
- lib/researchable/freedcamp_api/list_projects.rb
|
138
|
+
- lib/researchable/freedcamp_api/list_task_lists.rb
|
134
139
|
- lib/researchable/freedcamp_api/list_tasks.rb
|
135
140
|
- lib/researchable/freedcamp_api/sessions.rb
|
136
141
|
- lib/researchable/freedcamp_api/sessions/session.rb
|