qrapi-wrapper 0.6.0

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/lib/qrapi.rb +79 -0
  3. data/lib/qrapi/client.rb +58 -0
  4. data/lib/qrapi/error_handling_resourceable.rb +22 -0
  5. data/lib/qrapi/mappings/contact_mapping.rb +22 -0
  6. data/lib/qrapi/mappings/distribution_mapping.rb +68 -0
  7. data/lib/qrapi/mappings/division_mapping.rb +27 -0
  8. data/lib/qrapi/mappings/error_mapping.rb +19 -0
  9. data/lib/qrapi/mappings/group_mapping.rb +27 -0
  10. data/lib/qrapi/mappings/library_message_mapping.rb +20 -0
  11. data/lib/qrapi/mappings/mailing_list_mapping.rb +20 -0
  12. data/lib/qrapi/mappings/organization_mapping.rb +19 -0
  13. data/lib/qrapi/mappings/response_export_mapping.rb +14 -0
  14. data/lib/qrapi/mappings/responses_mapping.rb +45 -0
  15. data/lib/qrapi/mappings/survey_mapping.rb +33 -0
  16. data/lib/qrapi/mappings/user_mapping.rb +40 -0
  17. data/lib/qrapi/models/base_model.rb +22 -0
  18. data/lib/qrapi/models/distribution.rb +45 -0
  19. data/lib/qrapi/models/distribution/headers.rb +27 -0
  20. data/lib/qrapi/models/distribution/message.rb +26 -0
  21. data/lib/qrapi/models/distribution/recipients.rb +26 -0
  22. data/lib/qrapi/models/distribution/survey_link.rb +26 -0
  23. data/lib/qrapi/models/division.rb +32 -0
  24. data/lib/qrapi/models/group.rb +31 -0
  25. data/lib/qrapi/models/library_message.rb +27 -0
  26. data/lib/qrapi/models/mailing_list.rb +27 -0
  27. data/lib/qrapi/models/mailing_list/contact.rb +33 -0
  28. data/lib/qrapi/models/organization.rb +29 -0
  29. data/lib/qrapi/models/response.rb +40 -0
  30. data/lib/qrapi/models/response_export.rb +71 -0
  31. data/lib/qrapi/models/survey.rb +45 -0
  32. data/lib/qrapi/models/survey/expiration.rb +25 -0
  33. data/lib/qrapi/models/user.rb +44 -0
  34. data/lib/qrapi/resources/distribution_resource.rb +47 -0
  35. data/lib/qrapi/resources/division_resource.rb +24 -0
  36. data/lib/qrapi/resources/group_resource.rb +44 -0
  37. data/lib/qrapi/resources/library_message_resource.rb +41 -0
  38. data/lib/qrapi/resources/mailing_list_resource.rb +51 -0
  39. data/lib/qrapi/resources/organization_resource.rb +12 -0
  40. data/lib/qrapi/resources/response_export_resource.rb +49 -0
  41. data/lib/qrapi/resources/response_import_resource.rb +26 -0
  42. data/lib/qrapi/resources/survey_resource.rb +27 -0
  43. data/lib/qrapi/resources/user_resource.rb +35 -0
  44. data/lib/qrapi/utils/kartograph_optional_properties.rb +21 -0
  45. data/lib/qrapi/version.rb +3 -0
  46. metadata +271 -0
@@ -0,0 +1,71 @@
1
+ module QRAPI
2
+ class ResponseExport < BaseModel
3
+ attribute :id
4
+ attribute :percent_complete
5
+ attribute :file
6
+
7
+ # Unzips and maps the serialized responses to a Response object
8
+ #
9
+ # @return [QRAPI::Response]
10
+ def get_responses
11
+ unzip_responses(file)
12
+ end
13
+
14
+ private
15
+
16
+ # Creates a temporary zip file from api response, and maps the
17
+ # contents of the file inside to an array of QRAPI::Response models
18
+ # TODO: Add CSV support
19
+ # @return [QRAPI::Response]
20
+ def unzip_responses(response_zip)
21
+ File.open("/tmp/qualtrics_response_export_#{id}.zip", "wb") { |f| f.write response_zip }
22
+ responses = ""
23
+
24
+ Zip::File.open("/tmp/qualtrics_response_export_#{id}.zip") do |zip|
25
+ zip.each do |file|
26
+ case file.name
27
+ when /.+\.json/
28
+ responses = create_responses(file.get_input_stream.read, :json)
29
+ when /.+\.xml/
30
+ responses = create_responses(file.get_input_stream.read, :xml)
31
+ else
32
+ raise QRAPI::Error.new("Unkown Response Export file type for file: #{file.name}")
33
+ end
34
+ end
35
+ end
36
+
37
+ File.delete("/tmp/qualtrics_response_export_#{id}.zip")
38
+ responses
39
+ end
40
+
41
+ # Sends the serialized responses to the correct mapping function
42
+ # TODO: Add CSV Mapping
43
+ # @return [QRAPI::Response]
44
+ def create_responses(serialized_responses, f_type)
45
+ if (f_type == :json) || (f_type == :xml)
46
+ responses = ResponsesMapping.from_json_or_xml(serialized_responses, f_type)
47
+ end
48
+
49
+ responses
50
+ end
51
+
52
+ ##
53
+ # Make the model serializeable by ActiveModelSerializer
54
+ #
55
+ # @return [OpenStruct]
56
+ #
57
+ def self.model_name
58
+ OpenStruct.new(name: "QRAPI::ResponseExport",
59
+ klass: self,
60
+ singular: "qualtrics_response_export",
61
+ plural: "qualtrics_response_exports",
62
+ element: "response_exports",
63
+ human: "response_export",
64
+ collection: "qrapi/response_exports",
65
+ param_key: "qualtrics_response_exports",
66
+ i18n_key: "qrapi/response_exports",
67
+ route_key: "qualtrics_response_exports",
68
+ singular_route_key: "qualtrics_response_export")
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,45 @@
1
+ module QRAPI
2
+ class Survey < BaseModel
3
+ attribute :id
4
+ attribute :name
5
+ attribute :owner_id
6
+ attribute :organization_id
7
+ attribute :creation_date
8
+ attribute :last_modified
9
+ attribute :is_active
10
+ attribute :expiration
11
+ attribute :questions
12
+ attribute :export_column_map
13
+ attribute :blocks
14
+ attribute :flow
15
+ attribute :embedded_data
16
+ attribute :response_counts
17
+
18
+ ##
19
+ # Make the model serializeable by ActiveModelSerializer
20
+ #
21
+ # @return [OpenStruct]
22
+ #
23
+ def self.model_name
24
+ OpenStruct.new(name: "QRAPI::Survey",
25
+ klass: self,
26
+ singular: "qualtrics_survey",
27
+ plural: "qualtrics_surveys",
28
+ element: "survey",
29
+ human: "Survey",
30
+ collection: "qrapi/surveys",
31
+ param_key: "qualtrics_surveys",
32
+ i18n_key: "qrapi/surveys",
33
+ route_key: "qualtrics_surveys",
34
+ singular_route_key: "qualtrics_survey")
35
+ end
36
+
37
+ def created_at
38
+ creation_date
39
+ end
40
+
41
+ def updated_at
42
+ last_modified
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ module QRAPI
2
+ class Survey::Expiration < BaseModel
3
+ attribute :start_date
4
+ attribute :end_date
5
+
6
+ ##
7
+ # Make the model serializeable by ActiveModelSerializer
8
+ #
9
+ # @return [OpenStruct]
10
+ #
11
+ def self.model_name
12
+ OpenStruct.new(name: "QRAPI::MailingList",
13
+ klass: self,
14
+ singular: "qualtrics_survey_expiration",
15
+ plural: "qualtrics_survey_expirations",
16
+ element: "survey_expiration",
17
+ human: "survey_expiration",
18
+ collection: "qrapi/survey_expirations",
19
+ param_key: "qualtrics_survey_expirations",
20
+ i18n_key: "qrapi/survey_expirations",
21
+ route_key: "qualtrics_survey_expirations",
22
+ singular_route_key: "qualtrics_survey_expiration")
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ module QRAPI
2
+ class User < BaseModel
3
+ attribute :id
4
+ attribute :username
5
+ attribute :first_name
6
+ attribute :last_name
7
+ attribute :user_type
8
+ attribute :division_id
9
+ attribute :status
10
+ attribute :language
11
+ # attribute :permissions
12
+ attribute :organization_id
13
+ attribute :unsubscribed
14
+ attribute :account_creation_date
15
+ attribute :account_expiration_date
16
+ attribute :password_last_changed_date
17
+ attribute :password_expiration_date
18
+ attribute :last_login_date
19
+ attribute :response_counts
20
+
21
+ # Create only attributes
22
+ attribute :password
23
+ attribute :email
24
+
25
+ ##
26
+ # Make the model serializeable by ActiveModelSerializer
27
+ #
28
+ # @return [OpenStruct]
29
+ #
30
+ def self.model_name
31
+ OpenStruct.new(name: "QRAPI::MailingList",
32
+ klass: self,
33
+ singular: "qualtrics_user",
34
+ plural: "qualtrics_users",
35
+ element: "user",
36
+ human: "user",
37
+ collection: "qrapi/users",
38
+ param_key: "qualtrics_users",
39
+ i18n_key: "qrapi/users",
40
+ route_key: "qualtrics_users",
41
+ singular_route_key: "qualtrics_user")
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,47 @@
1
+ module QRAPI
2
+ class DistributionResource < ResourceKit::Resource
3
+ include ErrorHandlingResourceable
4
+
5
+ resources do
6
+ action :all, "GET /API/v3/distributions" do
7
+ query_keys surveyId: :survey_id, mailingListId: :mailing_list_id,
8
+ distributionRequestType: :distribution_request_type,
9
+ sendStartDate: :send_start_date, sendEndDate: :send_end_date
10
+
11
+ handler(200) do |response|
12
+ response_body = JSON.parse(response.body)["result"].to_json
13
+ DistributionMapping.extract_collection(response_body, :read)
14
+ end
15
+ end
16
+
17
+ action :find, "GET /API/v3/distributions/:id" do
18
+ query_keys surveyId: :survey_id
19
+ handler(200) { |response| DistributionMapping.extract_single(response.body, :read) }
20
+ end
21
+
22
+ action :create, "POST /API/v3/distributions" do
23
+ body { |object| DistributionMapping.representation_for(:create, object) }
24
+ handler(200) do |response, object|
25
+ object.id = JSON.parse(response.body)["result"]["id"]
26
+ object
27
+ end
28
+ end
29
+
30
+ action :create_thankyou, "POST /API/v3/distributions/:id/thankyous" do
31
+ body { |object| DistributionMapping.representation_for(:create_child, object) }
32
+ handler(200) do |response, object|
33
+ object.id = JSON.parse(response.body)["result"]["distributionId"]
34
+ object
35
+ end
36
+ end
37
+
38
+ action :create_reminder, "POST /API/v3/distributions/:id/reminders" do
39
+ body { |object| DistributionMapping.representation_for(:create_child, object) }
40
+ handler(200) do |response, object|
41
+ object.id = JSON.parse(response.body)["result"]["distributionId"]
42
+ object
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,24 @@
1
+ module QRAPI
2
+ class DivisionResource < ResourceKit::Resource
3
+ include ErrorHandlingResourceable
4
+
5
+ resources do
6
+ action :find, "GET /API/v3/divisions/:id" do
7
+ handler(200) { |response| DivisionMapping.extract_single(response.body, :read) }
8
+ end
9
+
10
+ action :create, "POST /API/v3/divisions" do
11
+ body { |object| DivisionMapping.representation_for(:create, object) }
12
+ handler(200) do |response, object|
13
+ object.id = JSON.parse(response.body)["result"]["id"]
14
+ object
15
+ end
16
+ end
17
+
18
+ action :update, "PUT /API/v3/divisions/:id" do
19
+ body { |object| DivisionMapping.representation_for(:update, object) }
20
+ handler(200) { |_| true }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ module QRAPI
2
+ class GroupResource < ResourceKit::Resource
3
+ include ErrorHandlingResourceable
4
+
5
+ resources do
6
+ action :all, "GET /API/v3/groups" do
7
+ handler(200) do |response|
8
+ body = JSON.parse(response.body)["result"].to_json
9
+ GroupMapping.extract_collection(body, :read)
10
+ end
11
+ end
12
+
13
+ action :find, "GET /API/v3/groups/:id" do
14
+ handler(200) { |response| GroupMapping.extract_single(response.body, :read) }
15
+ end
16
+
17
+ action :create, "POST /API/v3/groups" do
18
+ body { |object| GroupMapping.representation_for(object, :create) }
19
+ handler(200) do |response, object|
20
+ object.id = JSON.parse(response.body)["result"]["groupId"]
21
+ object
22
+ end
23
+ end
24
+
25
+ action :update, "PUT /API/v3/groups/:id" do
26
+ body { |object| GroupMapping.representation_for(object, :update) }
27
+ handler(200) { |_| true }
28
+ end
29
+
30
+ action :delete, "DELETE /API/v3/groups/:id" do
31
+ handler(200) { |_| true }
32
+ end
33
+
34
+ action :add_user, "POST /API/v3/groups/:id/members" do
35
+ body { |user_id| { userId: user_id }.to_json }
36
+ handler(200) { |_| true }
37
+ end
38
+
39
+ action :delete_user, "DELETE /API/v3/groups/:id/members/:user_id" do
40
+ handler(200) { |_| true }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ module QRAPI
2
+ class LibraryMessageResource < ResourceKit::Resource
3
+ include ErrorHandlingResourceable
4
+
5
+ resources do
6
+ action :all, "GET /API/v3/libraries/:library_id/messages" do
7
+ handler(200) do |response|
8
+ body = JSON.parse(response.body)["result"].to_json
9
+ LibraryMessageMapping.extract_collection(body, :read)
10
+ end
11
+ end
12
+
13
+ action :find, "GET /API/v3/libraries/:library_id/messages/:id" do
14
+ # Qualtrics doesn't return the id in the response
15
+ # so we have to assign it from the passed message_id
16
+ handler(200) do |response, id|
17
+ lib_msg = LibraryMessageMapping.extract_single(response.body, :read)
18
+ lib_msg.id = id
19
+ lib_msg
20
+ end
21
+ end
22
+
23
+ action :create, "POST /API/v3/libraries/:library_id/messages" do
24
+ body { |object| LibraryMessageMapping.representation_for(:create, object) }
25
+ handler(200) do |response, object|
26
+ object.id = JSON.parse(response.body)["result"]["id"]
27
+ object
28
+ end
29
+ end
30
+
31
+ action :update, "PUT /API/v3/libraries/:library_id/messages/:id" do
32
+ body { |object| LibraryMessageMapping.representation_for(:update, object) }
33
+ handler(200) { |_| true }
34
+ end
35
+
36
+ action :delete, "DELETE /API/v3/libraries/:library_id/messages/:id" do
37
+ handler(200) { |_| true }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,51 @@
1
+ module QRAPI
2
+ class MailingListResource < ResourceKit::Resource
3
+ include ErrorHandlingResourceable
4
+
5
+ resources do
6
+ action :all, "GET /API/v3/mailinglists" do
7
+ handler(200) do |response|
8
+ body = JSON.parse(response.body)["result"].to_json
9
+ MailingListMapping.extract_collection(body, :read)
10
+ end
11
+ end
12
+
13
+ action :find, "GET /API/v3/mailinglists/:id" do
14
+ handler(200) { |response| MailingListMapping.extract_single(response.body, :read) }
15
+ end
16
+
17
+ action :create, "POST /API/v3/mailinglists" do
18
+ body { |object| MailingListMapping.representation_for(:create, object) }
19
+ handler(200) do |response, object|
20
+ object.id = JSON.parse(response.body)["result"]["id"]
21
+ object
22
+ end
23
+ end
24
+
25
+ action :update, "PUT /API/v3/mailinglists/:id" do
26
+ body { |object| MailingListMapping.representation_for(:update, object) }
27
+ handler(200) { |_| true }
28
+ end
29
+
30
+ action :delete, "DELETE /API/v3/mailinglists/:id" do
31
+ handler(200) { |_| true }
32
+ end
33
+
34
+ action :list_contacts, "GET /API/v3/mailinglists/:id/contacts" do
35
+ handler(200) do |response|
36
+ body = JSON.parse(response.body)["result"].to_json
37
+ ContactMapping.extract_collection(body, :read)
38
+ end
39
+ end
40
+
41
+ action :update_contact, "PUT /API/v3/mailinglists/:id/contacts/:contact_id" do
42
+ body { |object| ContactMapping.representation_for(:update, object) }
43
+ handler(200) { |_| true }
44
+ end
45
+
46
+ action :delete_contact, "DELETE /API/v3/mailinglists/:id/contacts/:contact_id" do
47
+ handler(200) { |_| true }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,12 @@
1
+ module QRAPI
2
+ class OrganizationResource < ResourceKit::Resource
3
+ include ErrorHandlingResourceable
4
+
5
+ resources do
6
+ action :find do
7
+ path "/API/v3/organizations/:id"
8
+ handler(200) { |response| OrganizationMapping.extract_single(response.body, :read) }
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,49 @@
1
+ module QRAPI
2
+ class ResponseExportResource < ResourceKit::Resource
3
+ include ErrorHandlingResourceable
4
+
5
+ [:csv, :csv_2013, :xml, :json, :spss].each do |file_type|
6
+ define_method file_type do |opts|
7
+ opts[:file_type] = file_type
8
+ create(opts)
9
+ end
10
+ end
11
+
12
+ resources do
13
+ action :find, "GET /API/v3/responseexports/:id" do
14
+ handler(200) do |response, hash|
15
+ resp_exp = ResponseExportMapping.extract_single(response.body, :read)
16
+ resp_exp.id = hash[:id]
17
+
18
+ unless resp_exp.percent_complete < 100
19
+ resp_exp.file = get_file(id: hash[:id])
20
+ end
21
+
22
+ resp_exp
23
+ end
24
+ end
25
+
26
+ action :create, "POST /API/v3/responseexports" do
27
+ body do |hash|
28
+ params = { surveyId: hash[:survey_id], format: hash[:file_type] }
29
+ optional_params = [:last_response_id, :start_date, :end_date, :limit,
30
+ :included_question_ids, :use_label, :decimal_separator,
31
+ :seen_unanswered_record, :use_local_time]
32
+
33
+ optional_params.each do |optional_param|
34
+ key = optional_param.to_s.camelize(:lower).to_sym
35
+ params[key] = hash[optional_param] if hash.has_key?(optional_param)
36
+ end
37
+
38
+ params.to_json
39
+ end
40
+
41
+ handler(200) { |response| JSON.parse(response.body)["result"]["id"] }
42
+ end
43
+
44
+ action :get_file, "GET /API/v3/responseexports/:id/file" do
45
+ handler(200) { |response| response.body }
46
+ end
47
+ end
48
+ end
49
+ end