researchable-freedcamp-api 0.1.5 → 0.1.6
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 +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_lists.rb +37 -0
- 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 +7 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8548577689d043fe6092a9e0ae799567f47d84e0c6e69328c60672d55c4c5572
|
4
|
+
data.tar.gz: 6862254a6953128dd131af3e79b30c3db0c7f2b653030dbbcf68ef5322b0df47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b8f801e3292b50c989717d5b7306afc4ccafac6901c2f0bdc0ddce5591ab4e592ee394e6f06ffada6107d498cb1ecfb0d0271c45770ce993d6c91138a3857be
|
7
|
+
data.tar.gz: c47b871a253656a2d3e78e819d279f3a66a616bfac2afa1e5034acb98b4547da052003184322e92d4436bc22429479a109252c9fad119f9606423fcb7061eba2
|
@@ -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,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,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,21 @@
|
|
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
|
+
|
10
13
|
require_relative 'freedcamp_api/list_tasks'
|
11
14
|
require_relative 'freedcamp_api/update_task'
|
12
15
|
require_relative 'freedcamp_api/create_task'
|
13
16
|
|
17
|
+
require_relative 'freedcamp_api/get_user'
|
18
|
+
|
19
|
+
require_relative 'freedcamp_api/list_lists'
|
20
|
+
|
14
21
|
require_relative 'freedcamp_api/create_comment'
|
15
22
|
|
16
23
|
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.6
|
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-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_interaction
|
@@ -126,11 +126,15 @@ 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_lists.rb
|
132
135
|
- lib/researchable/freedcamp_api/list_milestones.rb
|
133
136
|
- lib/researchable/freedcamp_api/list_projects.rb
|
137
|
+
- lib/researchable/freedcamp_api/list_task_lists.rb
|
134
138
|
- lib/researchable/freedcamp_api/list_tasks.rb
|
135
139
|
- lib/researchable/freedcamp_api/sessions.rb
|
136
140
|
- lib/researchable/freedcamp_api/sessions/session.rb
|