qrapi-wrapper 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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