RedcapAPI 0.0.5 → 0.0.6a

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YWRmMmY4MDRhZmFhZWRkYTJjNGY2NjNmMjQ4Njk2NDUwMWJiNDYyNg==
5
- data.tar.gz: !binary |-
6
- NWU2OGY2NmExMTM1YjY2ZjgzOTRmYmZjZTM2ZjBkZjg5MWNhYmFjOQ==
2
+ SHA1:
3
+ metadata.gz: 3ecc5ee19022a7fe8d9bd20f08fb53039a48716b
4
+ data.tar.gz: 75037075c22cd9bac02d65cbc2e72b0c48ccf742
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NGY2MDNlNGUwMmUyZTA5MzczYTM0MWUwZGYxNDhkZDMyNjVjNGU2ZGYxOTBk
10
- MDhmYmE2ZmNhNTVmMGM0YmE2M2I0ODYyYjliNmIyYzczZTFmYzRiMDkzOGUy
11
- YjU5MmZhOGJmZDQyOGM2ZGFjMTk3ZWU1MzgwZGQxNWQ2YzRhZTg=
12
- data.tar.gz: !binary |-
13
- YWQ0ODcyNGNiYTI3NmEyMmIwMjAwZGE1YWNiZjkyNWU2YmM5NDllOGZmNjI3
14
- NDM2NWM2ODRmY2FjNGU1ZGM4MjY2MDFjNDZiOWE2NjljMTY5YTlmZmRmNDRh
15
- N2NlNWJhODJhYjY5YjAwMTAwNWZlMmIzM2IxODFhMTg0NWNlMmE=
6
+ metadata.gz: 4dabdab78f3a6409c34be703e68496441aed72fe378c7675ee7b05c46c0fed8b81b3da5074de123ecf691cdc8147e2ea2e93aa597d22cb4b278612b6455867fc
7
+ data.tar.gz: da28bddc0d8b639195a157713f7ac9348b1eb09ba6b3513e77e9a722b22b227ffe234b16cbf76c6a3fd998129e87b32bbc72ad4f4ef8fef2a3b744a4f18872ef
data/README.md CHANGED
@@ -3,11 +3,66 @@
3
3
  This is an api to utilize REDCAP api with ruby. This Gem requires mechanize as a dependency.
4
4
  it is based on instructions here http://sburns.org/2013/07/22/intro-to-redcap-api.html
5
5
 
6
+ This gem is under development and testing. If you would like to make changes or have comments, reach me at eugene@tranquiltech.io
7
+
8
+ Special thanks to mmcrockett for making great additions.
9
+
6
10
  To start:
11
+ ```ruby
12
+ r = RedcapAPI.new(token, url, parser)
13
+ ```
14
+ your institution has it's own url, and each project has it's own token, an optional 'parser' that defaults to JSON. See the test cases for how to use other parsers like Nokogiri::XML and CSV.
15
+
16
+ ```ruby
17
+ r.export(optional params)
18
+ ```
19
+ returns all records in JSON format, provide additional hash of parameters in you want to override or add any additional RedcapAPI options.
20
+
21
+ ```ruby
22
+ r.export_metadata(optional params)
23
+ ```
24
+ returns all metadata records in JSON format, provide additional hash of parameters in you want to override or add any additional RedcapAPI options.
25
+
26
+ ```
27
+ r.import(optional params)
28
+ ```
29
+ imports new records, the 'post' method is likely more helpful as it puts the 'data' in the correct format.
30
+
31
+ ```
32
+ r.api(optional params)
33
+ ```
34
+ returns the raw data, this allows you to return 'xml' or 'csv' instead of forcing 'json'. Simply override the params. Example r.api({:format => 'xml'}).
35
+ ```
36
+ r.get(optional record_id)
37
+ ```
38
+ returns all records in JSON format or a specific record if specified
39
+ ```
40
+ r.get_fields
41
+ ```
42
+ returns all fields for that instrument
43
+ ```
44
+ r.post(data)
45
+ ```
46
+ this will either update an old record or create a new one. the data should be in form of array of hashes or as a hash (for one item). dates are accepted in Date class or in strftime('%F') format.
47
+ for example
48
+ ```
49
+ data = {name: 'this is a test', field_2: Date.today}
50
+ r.post(data)
51
+ ```
52
+ creates a new object using the fields above. field names must match those in the existing project
53
+ "{\"count\": 1}" --> indicates the object posted.
7
54
 
8
- r = RedcapAPI.new(token, url) # your institution has it's own url, and each project has it's own token
55
+ to update an existing record:
56
+ ```
57
+ data = {record_id: 3, name: 'this is a test to update', field_2: Date.today}
58
+ r.post(data)
59
+ ```
60
+ this will update the record with record_id 3. if record_id 3 does not exist it will create an entry with that record id
9
61
 
10
- r.get(optional record_id) # returns all records in JSON format or a specific record if specified
62
+ There is also a helper class added to ruby Hash allowing you to convert a ruby array to a http-post style array. It was created after having some issues filtering on 'forms' and 'fields'
63
+ Example:
64
+ params = {:fields => ['record_id', 'lab_id'], :forms => ['slide_tracking', 'id_shipping']} # This is the data I want to send to RedcapAPI, limiting the fields and forms
65
+ r.export_metadata(params.to_http_post_array()) # This gets the metadata for only those fields/forms by using the newly added method on Hash 'to_http_post_array'.
11
66
 
12
67
  ## Contributing
13
68
 
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/testtask'
2
3
 
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ end
7
+
8
+ desc "Run tests"
9
+ task :default => :test
@@ -9,20 +9,10 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["eugyev"]
10
10
  spec.email = ["eugyev@gmail.com"]
11
11
  spec.summary = %q{This is an api to utilize REDCAP api with ruby. This Gem requires mechanize as a dependency.
12
- it is based on instructions here http://sburns.org/2013/07/22/intro-to-redcap-api.html
12
+ The backend is based on instructions here http://sburns.org/2013/07/22/intro-to-redcap-api.html
13
13
  }
14
14
  spec.description = %q{
15
- This gem is still under active development. Please contact me directly with any questions or suggestions.
16
-
17
- To start:
18
-
19
- r = RedcapAPI.new(token, url) # your institution has it's own url, and each project has it's own token
20
-
21
- r.get(optional record_id) # returns all records in JSON format or a specific record if specified
22
-
23
- r.get_fields # returns all fields for that instrument
24
-
25
- r.post(data) # this will either update an old record or create a new one. the data should be in form of array of hashes or as a hash (for one item). dates are accepted in Date class or in strftime('%F') format.
15
+ Please see Github Repo and Readme file https://github.com/eugyev/RedcapAPI
26
16
  }
27
17
  spec.homepage = ""
28
18
  spec.license = "MIT"
@@ -34,5 +24,8 @@ Gem::Specification.new do |spec|
34
24
 
35
25
  spec.add_development_dependency "bundler", "~> 1.6"
36
26
  spec.add_development_dependency "rake"
37
- spec.add_development_dependency "mechanize"
27
+ spec.add_development_dependency "csv"
28
+ spec.add_development_dependency "nokogiri"
29
+ spec.add_dependency "mechanize"
30
+ spec.add_dependency "json"
38
31
  end
@@ -1,13 +1,40 @@
1
1
  require "RedcapAPI/version"
2
+ require "json"
3
+ require "mechanize"
4
+ class Hash
5
+ def to_http_post_array
6
+ r = {}
7
+
8
+ self.each_key do |k|
9
+ if (false == self[k].is_a?(Array))
10
+ raise "!ERROR: Expecting hash value to be an Array."
11
+ end
12
+
13
+ self[k].each_with_index do |v,i|
14
+ r["#{k}[#{i}]"] = v
15
+ end
16
+ end
17
+
18
+ return r
19
+ end
20
+ end
21
+
2
22
  class RedcapAPI
3
- def initialize(token, url)
4
- @url = url
5
- @token = token
23
+ DEFAULT_PARAMS = {
24
+ :content => 'record',
25
+ :format => 'json',
26
+ :type => 'flat'
27
+ }
28
+
29
+ def initialize(token, url, parser = JSON)
30
+ @url = url
31
+ @payload = DEFAULT_PARAMS
32
+ @payload[:token] = token
33
+ @parser = parser
6
34
  end
7
35
 
8
36
  def get(record_id = nil)
9
- payload = {:token=>@token, :format=>"json", :content=>"record", :type => 'flat'}
10
- data = JSON.parse Mechanize.new.post(@url, payload).body
37
+ data = self.export()
11
38
  if record_id
12
39
  data = data.select{|x| x['record_id'] == record_id.to_s}
13
40
  end
@@ -15,8 +42,7 @@ require "RedcapAPI/version"
15
42
  end
16
43
 
17
44
  def get_fields
18
- payload = {:token=>@token, :format=>"json", :content=>"metadata"}
19
- response = JSON.parse Mechanize.new.post(@url, payload).body
45
+ response = export_metadata()
20
46
  if response
21
47
  response.collect {|r| r['field_name'] if r }
22
48
  end
@@ -25,8 +51,7 @@ require "RedcapAPI/version"
25
51
  def post(data)
26
52
  data = filter_data(data)
27
53
  data_string = data.to_json
28
- payload = {:token => @token, :format=> 'json', :content=>'record', :type => 'flat', :data => data_string}
29
- Mechanize.new.post(@url, payload).body
54
+ return self.import({:data => data_string})
30
55
  end
31
56
 
32
57
  def filter_data(data)
@@ -56,4 +81,22 @@ require "RedcapAPI/version"
56
81
  (max_entry.to_i + 1).to_s
57
82
  end
58
83
  end
84
+
85
+ def export(params = {})
86
+ return @parser.parse(api(params))
87
+ end
88
+
89
+ def export_metadata(params = {})
90
+ payload = {:content => 'metadata'}.merge(params)
91
+ return self.export(payload)
92
+ end
93
+
94
+ def import(params = {})
95
+ return api(params)
96
+ end
97
+
98
+ def api(params = {})
99
+ payload = @payload.merge(params)
100
+ return Mechanize.new.post(@url, payload).body
101
+ end
59
102
  end
@@ -1,3 +1,3 @@
1
1
  class RedcapAPI
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6a"
3
3
  end
@@ -0,0 +1,105 @@
1
+ require 'test/unit'
2
+ require 'RedcapAPI'
3
+ require 'csv'
4
+ require 'Nokogiri'
5
+
6
+ class Hash
7
+ def body
8
+ return self[:body]
9
+ end
10
+ end
11
+
12
+ class Mechanize
13
+ def post(url, payload)
14
+ v = {}
15
+
16
+ if ('json' == payload[:format])
17
+ if ('metadata' == payload[:content])
18
+ v[:body] = '[{"field_name":"record_id", "form_name":"form0"},{"field_name":"first_name", "form_name":"form0"},{"field_name":"trc_id", "form_name":"form0"}]'
19
+ else
20
+ v[:body] = '[{"record_id":"1", "trc_id":"b", "first_name":"bob"},{"record_id":"2", "trc_id":"c", "first_name":"chris"}]'
21
+ end
22
+ elsif ('xml' == payload[:format])
23
+ v[:body] = '<?xml version="1.0" encoding="UTF-8" ?><records><item><record_id><![CDATA[1]]></record_id><trc_id>b</trc_id><first_name>bob</first_name></item><item><record_id><![CDATA[2]]></record_id><trc_id>c</trc_id><first_name>chris</first_name></item></records>'
24
+ elsif ('csv' == payload[:format])
25
+ v[:body] = 'record_id,trc_id,first_name'
26
+ v[:body] << "\n"
27
+ v[:body] << '"1","b","bob"'
28
+ v[:body] << "\n"
29
+ v[:body] << '"2","c","chris"'
30
+ else
31
+ raise "!ERROR: unkown format '#{payload[:format]}'."
32
+ end
33
+
34
+ return v
35
+ end
36
+ end
37
+
38
+ class RedcapAPITest < Test::Unit::TestCase
39
+ def test_hash_extension
40
+ t = {:a => [1,2,3], :b => ["h", "i", "j"]}
41
+ e = {"a[0]" => 1, "a[1]" => 2, "a[2]" => 3, "b[0]" => "h", "b[1]" => "i", "b[2]" => "j"}
42
+ assert_equal(e, t.to_http_post_array)
43
+ end
44
+
45
+ def test_default_parser
46
+ default = RedcapAPI.new("", "").export()
47
+ json_data = RedcapAPI.new("", "", JSON).export({:format => 'json'})
48
+
49
+ assert_equal(json_data, default)
50
+ end
51
+
52
+ def test_xml_parser
53
+ xml_data = RedcapAPI.new("", "", Nokogiri::XML::Document).export({:format => 'xml'})
54
+ json_data = RedcapAPI.new("", "", JSON).export({:format => 'json'})
55
+ xml_to_json_data = []
56
+
57
+ xml_data.xpath(".//item").each do |item_node|
58
+ json_record = {}
59
+ item_node.children().each do |value_node|
60
+ json_record[value_node.name()] = value_node.content()
61
+ end
62
+ xml_to_json_data << json_record
63
+ end
64
+
65
+ assert_equal(json_data, xml_to_json_data)
66
+ end
67
+
68
+ def test_csv_parser
69
+ csv_data = RedcapAPI.new("", "", CSV).export({:format => 'csv'})
70
+ json_data = RedcapAPI.new("", "", JSON).export({:format => 'json'})
71
+ csv_to_json_data = []
72
+
73
+ csv_data.each_with_index do |record,i|
74
+ if (0 != i)
75
+ json_record = {}
76
+ record.each_with_index do |value,j|
77
+ json_record[csv_data[0][j]] = value
78
+ end
79
+ csv_to_json_data << json_record
80
+ end
81
+ end
82
+
83
+ assert_equal(json_data, csv_to_json_data)
84
+ end
85
+
86
+ def test_param_override
87
+ metadata = RedcapAPI.new("", "").export_metadata()
88
+ data = RedcapAPI.new("", "").export_metadata({:content => 'record'})
89
+
90
+ assert_not_equal(data, metadata)
91
+ end
92
+
93
+ def test_metadata
94
+ metadata = RedcapAPI.new("", "").export_metadata()
95
+ data = [{"field_name"=>"record_id", "form_name"=>"form0"},{"field_name"=>"first_name", "form_name"=>"form0"},{"field_name"=>"trc_id", "form_name"=>"form0"}]
96
+
97
+ assert_equal(data, metadata)
98
+ end
99
+
100
+ def test_get_fields
101
+ fields = RedcapAPI.new("", "").get_fields()
102
+
103
+ assert_equal(["record_id", "first_name", "trc_id"], fields)
104
+ end
105
+ end
metadata CHANGED
@@ -1,72 +1,108 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: RedcapAPI
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6a
5
5
  platform: ruby
6
6
  authors:
7
7
  - eugyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-13 00:00:00.000000000 Z
11
+ date: 2015-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.6'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: mechanize
42
+ name: csv
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mechanize
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
53
81
  - !ruby/object:Gem::Version
54
82
  version: '0'
55
- description: ! "\n This gem is still under active development. Please contact me
56
- directly with any questions or suggestions. \n \n To start:\n\n r = RedcapAPI.new(token,
57
- url) # your institution has it's own url, and each project has it's own token\n\n
58
- \ r.get(optional record_id) # returns all records in JSON format or a specific record
59
- if specified\n \n r.get_fields # returns all fields for that instrument\n \n
60
- \ r.post(data) # this will either update an old record or create a new one. the
61
- data should be in form of array of hashes or as a hash (for one item). dates are
62
- accepted in Date class or in strftime('%F') format. \n "
83
+ - !ruby/object:Gem::Dependency
84
+ name: json
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: "\n Please see Github Repo and Readme file https://github.com/eugyev/RedcapAPI\n
98
+ \ "
63
99
  email:
64
100
  - eugyev@gmail.com
65
101
  executables: []
66
102
  extensions: []
67
103
  extra_rdoc_files: []
68
104
  files:
69
- - .gitignore
105
+ - ".gitignore"
70
106
  - Gemfile
71
107
  - LICENSE.txt
72
108
  - README.md
@@ -74,6 +110,7 @@ files:
74
110
  - RedcapAPI.gemspec
75
111
  - lib/RedcapAPI.rb
76
112
  - lib/RedcapAPI/version.rb
113
+ - test/test_redcap_api.rb
77
114
  homepage: ''
78
115
  licenses:
79
116
  - MIT
@@ -84,19 +121,20 @@ require_paths:
84
121
  - lib
85
122
  required_ruby_version: !ruby/object:Gem::Requirement
86
123
  requirements:
87
- - - ! '>='
124
+ - - ">="
88
125
  - !ruby/object:Gem::Version
89
126
  version: '0'
90
127
  required_rubygems_version: !ruby/object:Gem::Requirement
91
128
  requirements:
92
- - - ! '>='
129
+ - - ">"
93
130
  - !ruby/object:Gem::Version
94
- version: '0'
131
+ version: 1.3.1
95
132
  requirements: []
96
133
  rubyforge_project:
97
134
  rubygems_version: 2.2.2
98
135
  signing_key:
99
136
  specification_version: 4
100
137
  summary: This is an api to utilize REDCAP api with ruby. This Gem requires mechanize
101
- as a dependency. it is based on instructions here http://sburns.org/2013/07/22/intro-to-redcap-api.html
102
- test_files: []
138
+ as a dependency. The backend is based on instructions here http://sburns.org/2013/07/22/intro-to-redcap-api.html
139
+ test_files:
140
+ - test/test_redcap_api.rb