dhis2 2.3.5 → 2.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/README.md +12 -1
- data/design.md +195 -0
- data/dhis2.gemspec +4 -0
- data/lib/dhis2.rb +11 -5
- data/lib/dhis2/api/analytic.rb +4 -2
- data/lib/dhis2/api/attribute.rb +2 -0
- data/lib/dhis2/api/base.rb +6 -4
- data/lib/dhis2/api/category_combo.rb +2 -0
- data/lib/dhis2/api/category_option_combo.rb +2 -0
- data/lib/dhis2/api/data_element.rb +5 -2
- data/lib/dhis2/api/data_element_group.rb +1 -0
- data/lib/dhis2/api/data_set.rb +2 -1
- data/lib/dhis2/api/data_value.rb +3 -1
- data/lib/dhis2/api/data_value_set.rb +4 -3
- data/lib/dhis2/api/event.rb +36 -0
- data/lib/dhis2/api/indicator.rb +2 -0
- data/lib/dhis2/api/organisation_unit.rb +3 -1
- data/lib/dhis2/api/organisation_unit_group.rb +2 -0
- data/lib/dhis2/api/organisation_unit_group_set.rb +6 -0
- data/lib/dhis2/api/organisation_unit_level.rb +2 -0
- data/lib/dhis2/api/program.rb +8 -0
- data/lib/dhis2/api/report.rb +2 -0
- data/lib/dhis2/api/report_table.rb +3 -1
- data/lib/dhis2/api/resource_table.rb +14 -0
- data/lib/dhis2/api/system_info.rb +2 -0
- data/lib/dhis2/api/user.rb +2 -0
- data/lib/dhis2/client.rb +23 -17
- data/lib/dhis2/collection_wrapper.rb +2 -0
- data/lib/dhis2/configuration.rb +2 -0
- data/lib/dhis2/import_error.rb +2 -0
- data/lib/dhis2/pager.rb +1 -0
- data/lib/dhis2/paginated_array.rb +2 -0
- data/lib/dhis2/status.rb +8 -1
- data/lib/dhis2/version.rb +3 -1
- metadata +65 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d03ac1a95b0c73815866f14268e03502d0912e4c
|
4
|
+
data.tar.gz: 0a10d402e5c0cf26418fae541a993f34b059d482
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13087348f19e9b435270f48c08fde3b808892ddd5a8db78178166f0549e05ab62774f3ac295a0adfa5ecef3d04fe9591e09b837115096f261ce8e417b69f6687
|
7
|
+
data.tar.gz: 5a803e3506df42cc61f6b205d16858be21200f774628f0f8485d279b5ee0e8ebc8509fbe7db6b21faaff3065f392e2aa262a2fae7859bad5308e338dd79ed05d
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.0
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Dhis2
|
2
2
|
|
3
3
|
<a href="https://codeclimate.com/github/BLSQ/dhis2"><img src="https://codeclimate.com/github/BLSQ/dhis2/badges/gpa.svg" /></a>
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/dhis2.svg)](https://badge.fury.io/rb/dhis2)
|
4
5
|
|
5
6
|
Basic DHIS2 API client for Ruby.
|
6
7
|
|
@@ -147,6 +148,9 @@ The API is currently limited to actions on the following elements:
|
|
147
148
|
* `User`
|
148
149
|
* `Report`
|
149
150
|
* `ReportTable`
|
151
|
+
* `Program`
|
152
|
+
* `Events`
|
153
|
+
* `ResourceTables`
|
150
154
|
|
151
155
|
## Update
|
152
156
|
|
@@ -190,9 +194,16 @@ DHIS2 API does not return the ids of the created elements, but you can retreive
|
|
190
194
|
status = Dhis2.client.data_elements.create(elements)
|
191
195
|
element = Dhis2.client.data_elements.find_by(name: "TesTesT2")
|
192
196
|
|
197
|
+
|
198
|
+
## Trigger analytics
|
199
|
+
|
200
|
+
You can trigger Analytics with
|
201
|
+
|
202
|
+
Dhis2.client.resource_tables.analytics
|
203
|
+
|
193
204
|
## Development
|
194
205
|
|
195
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. Note that the tests are using the DHIS2 demo server, which is reset every day but can be updated by anyone - so if someone change the password of the default user, the tests are going to fail.
|
206
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` and `bundle exec rspec` to run the tests. Note that the tests are using the DHIS2 demo server, which is reset every day but can be updated by anyone - so if someone change the password of the default user, the tests are going to fail.
|
196
207
|
|
197
208
|
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
198
209
|
|
data/design.md
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
# Design
|
2
|
+
|
3
|
+
Some internal notes about the application - may be of interest to visitors also.
|
4
|
+
|
5
|
+
## Why a wrapper?
|
6
|
+
|
7
|
+
A HTTP request:
|
8
|
+
|
9
|
+
response = Net::HTTP.get('https://play.dhis2.org/demo', '/api/organisationUnits?filter=name:eq:Baoma&fields=[id,name]')
|
10
|
+
org_units = JSON.parse(response)
|
11
|
+
|
12
|
+
We need basic auth:
|
13
|
+
|
14
|
+
uri = URI('https://play.dhis2.org/demo/api/organisationUnits?filter=name:eq:Baoma&fields=[id,name]')
|
15
|
+
|
16
|
+
req = Net::HTTP::Get.new(uri)
|
17
|
+
req.basic_auth 'user', 'pass'
|
18
|
+
|
19
|
+
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
|
20
|
+
http.request(req)
|
21
|
+
}
|
22
|
+
puts res.body
|
23
|
+
|
24
|
+
We need to connect to various DHIS2 clients:
|
25
|
+
|
26
|
+
project = Project.find(1)
|
27
|
+
user = project.dhis2_user
|
28
|
+
password = project.dhis2_password
|
29
|
+
url = project.dhis2_url
|
30
|
+
|
31
|
+
uri = URI("#{url}/api/organisationUnits?filter=name:eq:Baoma&fields=[id,name]")
|
32
|
+
|
33
|
+
req = Net::HTTP::Get.new(uri)
|
34
|
+
req.basic_auth user, password
|
35
|
+
|
36
|
+
...
|
37
|
+
|
38
|
+
and this all over the place
|
39
|
+
|
40
|
+
A bit better with Rest Client:
|
41
|
+
|
42
|
+
response = RestClient.get 'https://play.dhis2.org/demo/api/organisationUnits', {params: {filter: "name:eq:Baoma", fields: '[id,name]'}}
|
43
|
+
|
44
|
+
But still:
|
45
|
+
|
46
|
+
- url all over the place
|
47
|
+
- user/passwords all over the place
|
48
|
+
- need to parse the JSON after (where is the data?)
|
49
|
+
|
50
|
+
vs:
|
51
|
+
|
52
|
+
client = Dhis2::Client.new(user: "admin", password: "district", url: "https://play.dhis2.org/demo")
|
53
|
+
|
54
|
+
# then:
|
55
|
+
|
56
|
+
org_units = client.organisation_units.list
|
57
|
+
org_units = client.organisation_units.list(fields: :all)
|
58
|
+
|
59
|
+
## Topics
|
60
|
+
|
61
|
+
### OpenStructs
|
62
|
+
|
63
|
+
OpenStruct: create an object with any fields you want from a Hash:
|
64
|
+
|
65
|
+
s = OpenStruct.new
|
66
|
+
s.name = "Van Aken"
|
67
|
+
s.first_name = "Martin"
|
68
|
+
s # name=Van Aken, first_name=Martin
|
69
|
+
|
70
|
+
Hash with object like syntax (nicer) - can be created from a Hash, so working very well with JSON:
|
71
|
+
|
72
|
+
response = RestClient.get 'https://play.dhis2.org/demo/api/organisationUnits/123'
|
73
|
+
raw = JSON.parse(response)
|
74
|
+
ou = OpenStruct.new(raw) # got a nice object out of JSON
|
75
|
+
|
76
|
+
### Multi client
|
77
|
+
|
78
|
+
Initial API was very much ActiveRecord like:
|
79
|
+
|
80
|
+
OrganisationUnit.find(id)
|
81
|
+
DataElement.list(filter: "name:like:param")
|
82
|
+
|
83
|
+
we had to move to support multi clients:
|
84
|
+
|
85
|
+
client.organisation_units.find(id)
|
86
|
+
client.data_elements.list(filter: "name:like:param")
|
87
|
+
|
88
|
+
### Case conversion
|
89
|
+
|
90
|
+
Url is CamelCase, but this is not very ruby-ish:
|
91
|
+
|
92
|
+
ous = client.organisationUnits
|
93
|
+
puts ous.first.displayName
|
94
|
+
|
95
|
+
so we convert everything we get back to snake case.
|
96
|
+
|
97
|
+
### Status and error messages
|
98
|
+
|
99
|
+
We create a Status object able to answer to simple questions such as "was the call successful" - this is different depending on the DHIS2 version, and the usage of HTTP status code is not always consistent (it tend to return 200 even when a creation fail for instance).
|
100
|
+
|
101
|
+
### Version control
|
102
|
+
|
103
|
+
The Gem also help with the management of different versions of DHIS2, resolving some differences without impacting the end user.
|
104
|
+
|
105
|
+
## How it works:
|
106
|
+
|
107
|
+
class Indicator < Base
|
108
|
+
end
|
109
|
+
|
110
|
+
report = client.indicators.find("xxx")
|
111
|
+
puts report.name # "Deliveries coverage"
|
112
|
+
|
113
|
+
### A bit of meta programming for finders:
|
114
|
+
|
115
|
+
class OrganisationUnit
|
116
|
+
def self.find(id)
|
117
|
+
execute("/organisationUnits/#{id}")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class DataElement
|
122
|
+
def self.find(id)
|
123
|
+
execute("/dataElements/#{id}")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
To:
|
128
|
+
|
129
|
+
class Base
|
130
|
+
def self.find(id)
|
131
|
+
execute("#{resource_name}/#{id}")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
class DataElement < Base
|
136
|
+
def self.resource_name
|
137
|
+
"dataElements"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
To:
|
142
|
+
|
143
|
+
class Base
|
144
|
+
def self.find(id)
|
145
|
+
execute("#{resource_name}/#{id}")
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.resource_name
|
149
|
+
simple_name = name.split("::").last
|
150
|
+
simple_name[0].downcase + simple_name[1..-1] + "s"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class DataElement < Base
|
155
|
+
end
|
156
|
+
|
157
|
+
### A bit of meta programming for objects
|
158
|
+
|
159
|
+
We want something such:
|
160
|
+
|
161
|
+
client.organisation_units.find(id)
|
162
|
+
client.data_elements.find(id)
|
163
|
+
client.data_sets.find(id)
|
164
|
+
...
|
165
|
+
|
166
|
+
Again, those are just the "resource names" - no need to repeat ourselves.
|
167
|
+
|
168
|
+
We want
|
169
|
+
|
170
|
+
client.data_sets.find(id)
|
171
|
+
|
172
|
+
to call the `find` method on the DataSet class.
|
173
|
+
|
174
|
+
We want one method on client for each class that inherit from Base:
|
175
|
+
|
176
|
+
Enter `inherited` - a method called each time a class inherit from this one:
|
177
|
+
|
178
|
+
class Base
|
179
|
+
def self.inherited(base)
|
180
|
+
Dhis2::Client.register_resource(base)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
We can use `define_method` to create a method for the given class (we underscore the name again as above):
|
185
|
+
|
186
|
+
class Client
|
187
|
+
def self.register_resource(resource_class)
|
188
|
+
class_name = resource_class.name.split("::").last
|
189
|
+
method_name = underscore(class_name) + "s"
|
190
|
+
define_method(method_name) do
|
191
|
+
CollectionWrapper.new(resource_class, self)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
data/dhis2.gemspec
CHANGED
@@ -28,4 +28,8 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "faker", "~> 1.6", ">= 1.6.3"
|
29
29
|
spec.add_development_dependency "byebug"
|
30
30
|
|
31
|
+
spec.add_development_dependency "rspec"
|
32
|
+
spec.add_development_dependency "webmock"
|
33
|
+
spec.add_development_dependency "simplecov"
|
34
|
+
spec.add_development_dependency "rest-client-logger"
|
31
35
|
end
|
data/lib/dhis2.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "rest-client"
|
3
4
|
require "json"
|
4
5
|
require "ostruct"
|
@@ -17,6 +18,7 @@ require_relative "dhis2/client"
|
|
17
18
|
|
18
19
|
require_relative "dhis2/api/base"
|
19
20
|
require_relative "dhis2/api/category_combo"
|
21
|
+
require_relative "dhis2/api/category_option_combo"
|
20
22
|
require_relative "dhis2/api/organisation_unit"
|
21
23
|
require_relative "dhis2/api/data_element"
|
22
24
|
require_relative "dhis2/api/data_element_group"
|
@@ -27,23 +29,27 @@ require_relative "dhis2/api/organisation_unit_level"
|
|
27
29
|
require_relative "dhis2/api/indicator"
|
28
30
|
require_relative "dhis2/api/analytic"
|
29
31
|
require_relative "dhis2/api/organisation_unit_group"
|
32
|
+
require_relative "dhis2/api/organisation_unit_group_set"
|
30
33
|
require_relative "dhis2/api/system_info"
|
31
34
|
require_relative "dhis2/api/attribute"
|
32
35
|
require_relative "dhis2/api/user"
|
36
|
+
require_relative "dhis2/api/event"
|
37
|
+
require_relative "dhis2/api/program"
|
33
38
|
require_relative "dhis2/api/report_table"
|
39
|
+
require_relative "dhis2/api/resource_table"
|
34
40
|
require_relative "dhis2/api/report"
|
35
41
|
|
36
42
|
module Dhis2
|
37
43
|
class << self
|
38
44
|
def client
|
39
45
|
if @client.nil?
|
40
|
-
if config.user.nil? && config.password.nil?
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
@client ||= if config.user.nil? && config.password.nil?
|
47
|
+
Dhis2::Client.new(config.url)
|
48
|
+
else
|
49
|
+
Dhis2::Client.new(url: config.url,
|
44
50
|
user: config.user,
|
45
51
|
password: config.password)
|
46
|
-
|
52
|
+
end
|
47
53
|
else
|
48
54
|
@client
|
49
55
|
end
|
data/lib/dhis2/api/analytic.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dhis2
|
2
4
|
module Api
|
3
5
|
class Analytic < Base
|
@@ -8,9 +10,9 @@ module Dhis2
|
|
8
10
|
[:dimension, "dx:#{data_elements}"],
|
9
11
|
[:dimension, "pe:#{periods}"]
|
10
12
|
]
|
11
|
-
params << [:filter,
|
13
|
+
params << [:filter, filter.to_s] if filter
|
12
14
|
|
13
|
-
client.get(
|
15
|
+
client.get(resource_name, RestClient::ParamsArray.new(params))
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
data/lib/dhis2/api/attribute.rb
CHANGED
data/lib/dhis2/api/base.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dhis2
|
2
4
|
module Api
|
3
5
|
class Base < OpenStruct
|
@@ -79,7 +81,7 @@ module Dhis2
|
|
79
81
|
end
|
80
82
|
|
81
83
|
def initialize(client, raw_data)
|
82
|
-
raw_data["display_name"] ||= raw_data["name"]
|
84
|
+
raw_data["display_name"] ||= raw_data["name"] # for backward compatbility with v2.19
|
83
85
|
super(raw_data)
|
84
86
|
self.client = client
|
85
87
|
end
|
@@ -93,12 +95,12 @@ module Dhis2
|
|
93
95
|
end
|
94
96
|
|
95
97
|
def add_relation(relation, relation_id)
|
96
|
-
client.post("#{self.class.resource_name}/#{id}/#{relation}/#{relation_id}",{})
|
98
|
+
client.post("#{self.class.resource_name}/#{id}/#{relation}/#{relation_id}", {})
|
97
99
|
self
|
98
100
|
end
|
99
101
|
|
100
102
|
def remove_relation(relation, relation_id)
|
101
|
-
client.delete("#{self.class.resource_name}/#{id}/#{relation}/#{relation_id}",{})
|
103
|
+
client.delete("#{self.class.resource_name}/#{id}/#{relation}/#{relation_id}", {})
|
102
104
|
self
|
103
105
|
end
|
104
106
|
|
@@ -112,7 +114,7 @@ module Dhis2
|
|
112
114
|
end
|
113
115
|
|
114
116
|
def update
|
115
|
-
client.put("#{self.class.resource_name}/#{id}",
|
117
|
+
client.put("#{self.class.resource_name}/#{id}", to_h)
|
116
118
|
end
|
117
119
|
end
|
118
120
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dhis2
|
2
4
|
module Api
|
3
5
|
class DataElement < Base
|
4
6
|
class << self
|
5
|
-
def create(client, elements)
|
7
|
+
def create(client, elements, query_params = { preheat_cache: false })
|
6
8
|
elements = [elements].flatten
|
7
9
|
category_combo = client.category_combos.find_by(name: "default")
|
8
10
|
|
@@ -17,12 +19,13 @@ module Dhis2
|
|
17
19
|
aggregation_type: element[:aggregation_type] || "SUM",
|
18
20
|
type: element[:type] || "int", # for backward compatbility
|
19
21
|
aggregation_operator: element[:aggregation_type] || "SUM", # for backward compatbility
|
22
|
+
zero_is_significant: element[:zero_is_significant] || true,
|
20
23
|
category_combo: { id: category_combo.id, name: category_combo.name }
|
21
24
|
}
|
22
25
|
end
|
23
26
|
}
|
24
27
|
|
25
|
-
response = client.post("metadata", data_element)
|
28
|
+
response = client.post("metadata", data_element, client.class.deep_change_case(query_params, :camelize))
|
26
29
|
Dhis2::Status.new(response)
|
27
30
|
end
|
28
31
|
end
|
data/lib/dhis2/api/data_set.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dhis2
|
3
4
|
module Api
|
4
5
|
class DataSet < Base
|
@@ -15,7 +16,7 @@ module Dhis2
|
|
15
16
|
short_name: set[:short_name],
|
16
17
|
code: set[:code],
|
17
18
|
period_type: "Monthly",
|
18
|
-
data_elements:
|
19
|
+
data_elements: set[:data_element_ids] ? set[:data_element_ids].map { |id| { id: id } } : [],
|
19
20
|
organisation_units: set[:organisation_unit_ids] ? set[:organisation_unit_ids].map { |id| { id: id } } : [],
|
20
21
|
category_combo: { id: category_combo.id, name: category_combo.name }
|
21
22
|
}
|
data/lib/dhis2/api/data_value.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dhis2
|
2
4
|
module Api
|
3
5
|
class DataValue < Base
|
@@ -5,7 +7,7 @@ module Dhis2
|
|
5
7
|
def find(client, period:, organisation_unit:, data_element:)
|
6
8
|
params = { pe: period, ou: organisation_unit, de: data_element }
|
7
9
|
|
8
|
-
client.get(
|
10
|
+
client.get(resource_name, params).first
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Dhis2
|
3
4
|
module Api
|
4
5
|
class DataValueSet < Base
|
@@ -20,12 +21,12 @@ module Dhis2
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def build_list_url(_client, options)
|
23
|
-
params = [build_what_url(options),
|
24
|
+
params = [build_what_url(options), build_when_url(options), build_where_url(options)].join("&")
|
24
25
|
resource_name + "?" + params
|
25
26
|
end
|
26
27
|
|
27
28
|
def build_what_url(options)
|
28
|
-
data_set_ids
|
29
|
+
data_set_ids = options[:data_sets]
|
29
30
|
if data_set_ids
|
30
31
|
data_sets_url = data_set_ids.map { |ds| "dataSet=#{ds}" }.join("&")
|
31
32
|
else
|
@@ -50,7 +51,7 @@ module Dhis2
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def build_where_url(options)
|
53
|
-
children
|
54
|
+
children = options[:children] || true
|
54
55
|
organisation_unit_id = options[:organisation_unit]
|
55
56
|
organisation_unit_group = options[:organisation_unit_group]
|
56
57
|
if organisation_unit_id
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dhis2
|
4
|
+
module Api
|
5
|
+
class Event < Base
|
6
|
+
def id
|
7
|
+
event
|
8
|
+
end
|
9
|
+
class << self
|
10
|
+
def format_query_parameters(options)
|
11
|
+
|
12
|
+
params = []
|
13
|
+
params.push([:page, options[:page]]) if options[:page]
|
14
|
+
params.push([:pageSize, options[:page_size]]) if options[:page_size]
|
15
|
+
params.push([:fields, format_fields(options[:fields])]) if options[:fields]
|
16
|
+
params.concat(format_filter(options[:filter])) if options[:filter]
|
17
|
+
params.push([:program, options[:program]]) if options[:program]
|
18
|
+
params.push([:orgUnit, options[:org_unit]]) if options[:org_unit]
|
19
|
+
params.push([:trackedEntityInstance, options[:tracked_entity_instance]]) if options[:tracked_entity_instance]
|
20
|
+
|
21
|
+
RestClient::ParamsArray.new(params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create(client, tuples)
|
25
|
+
begin
|
26
|
+
body = { resource_name.to_sym => tuples }
|
27
|
+
response = client.post(resource_name, body)
|
28
|
+
rescue RestClient::Conflict => e
|
29
|
+
response = Dhis2::Client.deep_change_case(JSON.parse(e.response.body), :underscore)
|
30
|
+
end
|
31
|
+
Dhis2::Status.new(response)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/dhis2/api/indicator.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dhis2
|
2
4
|
module Api
|
3
5
|
class OrganisationUnit < Base
|
@@ -15,7 +17,7 @@ module Dhis2
|
|
15
17
|
elsif options.any?
|
16
18
|
params = []
|
17
19
|
options.each do |name, value|
|
18
|
-
params << [name, value]
|
20
|
+
params << [client.class.camelize(name.to_s, false), value]
|
19
21
|
end
|
20
22
|
params = client.class.deep_change_case(params, :camelize)
|
21
23
|
json_response = client.get("#{resource_name}/#{id}", RestClient::ParamsArray.new(params))
|
data/lib/dhis2/api/report.rb
CHANGED
data/lib/dhis2/api/user.rb
CHANGED
data/lib/dhis2/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dhis2
|
2
4
|
class Client
|
3
5
|
def self.register_resource(resource_class)
|
@@ -7,11 +9,13 @@ module Dhis2
|
|
7
9
|
CollectionWrapper.new(resource_class, self)
|
8
10
|
end
|
9
11
|
end
|
12
|
+
SUPPORTER_CASE_CHANGES = %i[underscore camelize].freeze
|
10
13
|
|
11
14
|
def self.deep_change_case(hash, type)
|
15
|
+
raise "unsupported case changes #{type} vs #{SUPPORTER_CASE_CHANGES}" unless SUPPORTER_CASE_CHANGES.include?(type)
|
12
16
|
case hash
|
13
17
|
when Array
|
14
|
-
hash.map {|v| deep_change_case(v, type) }
|
18
|
+
hash.map { |v| deep_change_case(v, type) }
|
15
19
|
when Hash
|
16
20
|
new_hash = {}
|
17
21
|
hash.each do |k, v|
|
@@ -25,19 +29,19 @@ module Dhis2
|
|
25
29
|
end
|
26
30
|
|
27
31
|
def self.camelize(string, uppercase_first_letter = true)
|
28
|
-
if uppercase_first_letter
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{
|
32
|
+
string = if uppercase_first_letter
|
33
|
+
string.sub(/^[a-z\d]*/) { $&.capitalize }
|
34
|
+
else
|
35
|
+
string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
36
|
+
end
|
37
|
+
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}" }.gsub("/", "::")
|
34
38
|
end
|
35
39
|
|
36
40
|
def self.underscore(camel_cased_word)
|
37
41
|
return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
|
38
|
-
word = camel_cased_word.to_s.gsub(/::/,
|
39
|
-
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
40
|
-
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
42
|
+
word = camel_cased_word.to_s.gsub(/::/, "/")
|
43
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
44
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
41
45
|
word.tr!("-", "_")
|
42
46
|
word.downcase!
|
43
47
|
word
|
@@ -54,11 +58,12 @@ module Dhis2
|
|
54
58
|
url.user = CGI.escape(options[:user])
|
55
59
|
url.password = CGI.escape(options[:password])
|
56
60
|
@base_url = url.to_s
|
57
|
-
@verify_ssl = options[:no_ssl_verification] ? OpenSSL::SSL::VERIFY_NONE :
|
61
|
+
@verify_ssl = options[:no_ssl_verification] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
|
62
|
+
@timeout = options[:timeout] ? options[:timeout].to_i : 120
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
61
|
-
def post(path, payload, query_params = {})
|
66
|
+
def post(path, payload = nil, query_params = {})
|
62
67
|
execute(:post, uri(path), headers, query_params, payload)
|
63
68
|
end
|
64
69
|
|
@@ -82,11 +87,12 @@ module Dhis2
|
|
82
87
|
|
83
88
|
def execute(method, url, headers, query_params = {}, payload = nil)
|
84
89
|
query = {
|
85
|
-
method:
|
86
|
-
url:
|
87
|
-
headers:
|
88
|
-
payload:
|
89
|
-
verify_ssl: @verify_ssl
|
90
|
+
method: method,
|
91
|
+
url: url,
|
92
|
+
headers: { params: query_params }.merge(headers),
|
93
|
+
payload: payload ? self.class.deep_change_case(payload, :camelize).to_json : nil,
|
94
|
+
verify_ssl: @verify_ssl,
|
95
|
+
timeout: @timeout
|
90
96
|
}
|
91
97
|
|
92
98
|
raw_response = RestClient::Request.execute(query)
|
data/lib/dhis2/configuration.rb
CHANGED
data/lib/dhis2/import_error.rb
CHANGED
data/lib/dhis2/pager.rb
CHANGED
data/lib/dhis2/status.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dhis2
|
2
4
|
class Status
|
3
5
|
attr_reader :raw_status
|
@@ -12,7 +14,7 @@ module Dhis2
|
|
12
14
|
summary["status"] == "SUCCESS"
|
13
15
|
end
|
14
16
|
end
|
15
|
-
[
|
17
|
+
%w[SUCCESS OK].include?(@raw_status["status"])
|
16
18
|
end
|
17
19
|
|
18
20
|
def total_imported
|
@@ -31,5 +33,10 @@ module Dhis2
|
|
31
33
|
return [] unless @raw_status["import_type_summaries"]
|
32
34
|
@raw_status["import_type_summaries"].map { |summary| summary["last_imported"] }
|
33
35
|
end
|
36
|
+
|
37
|
+
def import_summaries
|
38
|
+
return [] unless @raw_status["response"]["import_summaries"]
|
39
|
+
@raw_status["response"]["import_summaries"].map { |it| OpenStruct.new(it) }
|
40
|
+
end
|
34
41
|
end
|
35
42
|
end
|
data/lib/dhis2/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dhis2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Van Aken
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03
|
11
|
+
date: 2017-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -114,6 +114,62 @@ dependencies:
|
|
114
114
|
- - ">="
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rspec
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: webmock
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: simplecov
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: rest-client-logger
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
117
173
|
description: Allows to retreive items from a DHIS2 server in a more "Ruby way".
|
118
174
|
email:
|
119
175
|
- mvanaken@bluesquare.org
|
@@ -122,7 +178,9 @@ extensions: []
|
|
122
178
|
extra_rdoc_files: []
|
123
179
|
files:
|
124
180
|
- ".gitignore"
|
181
|
+
- ".rspec"
|
125
182
|
- ".rubocop.yml"
|
183
|
+
- ".ruby-version"
|
126
184
|
- ".travis.yml"
|
127
185
|
- CODE_OF_CONDUCT.md
|
128
186
|
- Gemfile
|
@@ -131,6 +189,7 @@ files:
|
|
131
189
|
- Rakefile
|
132
190
|
- bin/console
|
133
191
|
- bin/setup
|
192
|
+
- design.md
|
134
193
|
- dhis2.gemspec
|
135
194
|
- lib/dhis2.rb
|
136
195
|
- lib/dhis2/api/analytic.rb
|
@@ -143,12 +202,16 @@ files:
|
|
143
202
|
- lib/dhis2/api/data_set.rb
|
144
203
|
- lib/dhis2/api/data_value.rb
|
145
204
|
- lib/dhis2/api/data_value_set.rb
|
205
|
+
- lib/dhis2/api/event.rb
|
146
206
|
- lib/dhis2/api/indicator.rb
|
147
207
|
- lib/dhis2/api/organisation_unit.rb
|
148
208
|
- lib/dhis2/api/organisation_unit_group.rb
|
209
|
+
- lib/dhis2/api/organisation_unit_group_set.rb
|
149
210
|
- lib/dhis2/api/organisation_unit_level.rb
|
211
|
+
- lib/dhis2/api/program.rb
|
150
212
|
- lib/dhis2/api/report.rb
|
151
213
|
- lib/dhis2/api/report_table.rb
|
214
|
+
- lib/dhis2/api/resource_table.rb
|
152
215
|
- lib/dhis2/api/system_info.rb
|
153
216
|
- lib/dhis2/api/user.rb
|
154
217
|
- lib/dhis2/client.rb
|