sunspot4r 0.0.1

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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Josh Dennis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,3 @@
1
+ == Sunspot4R
2
+
3
+ You should document your project here.
data/README.markdown ADDED
@@ -0,0 +1,21 @@
1
+ # Daxko_Connect
2
+
3
+ Ruby wrapper for [DAXKO Connect](http://www.daxko.com/connect).
4
+
5
+ Based on the original Sunspot4R written by Tony Summerville's (tony.summerville@daxko.com).
6
+
7
+ ## Installation
8
+
9
+ sudo gem install daxko_connect
10
+
11
+ ## Usage
12
+
13
+ ### Authenticate
14
+
15
+ ### Examples
16
+
17
+ ## TODO
18
+
19
+ ## Copyright
20
+
21
+ Copyright (c) 2010 [Josh Dennis](http://joshdennis.net). See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "sunspot4r"
8
+ gem.summary = %Q{Ruby wrapper for DAXKO Sunspot}
9
+ gem.description = %Q{Ruby wrapper for DAXKO Sunspot}
10
+ gem.email = "dennijo@gmail.com"
11
+ gem.homepage = "http://github.com/dennijo/sunspot4R"
12
+ gem.authors = ['Tony Summerville', 'Josh Dennis']
13
+ gem.files = FileList["[A-Z]*", "{lib,test}/**/*"]
14
+ gem.add_dependency('savon', '>= 0.7.8')
15
+ gem.add_dependency('shoulda')
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'test'
25
+ test.ruby_opts << '-rubygems'
26
+ test.pattern = 'test/**/*_test.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |test|
33
+ test.libs << 'test'
34
+ test.pattern = 'test/**/test_*.rb'
35
+ test.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :test => :check_dependencies
44
+
45
+ task :default => :test
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "daxko_connect #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/Sunspot4R.gemspec ADDED
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sunspot4r}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tony Summerville", "Josh Dennis"]
12
+ s.date = %q{2010-08-04}
13
+ s.description = %q{Ruby wrapper for DAXKO Sunspot}
14
+ s.email = %q{dennijo@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README",
18
+ "README.markdown"
19
+ ]
20
+ s.files = [
21
+ "LICENSE",
22
+ "README",
23
+ "README.markdown",
24
+ "Rakefile",
25
+ "Sunspot4R.gemspec",
26
+ "VERSION",
27
+ "lib/ext/savon/request.rb",
28
+ "lib/sunspot4r.rb",
29
+ "lib/sunspot4r/base_sunspot_service_client.rb",
30
+ "lib/sunspot4r/object_service_client.rb",
31
+ "lib/sunspot4r/security_service_client.rb",
32
+ "lib/sunspot4r/system_service_client.rb",
33
+ "test/config.yml",
34
+ "test/object_service_client_test.rb",
35
+ "test/security_service_client_test.rb",
36
+ "test/system_service_client_test.rb",
37
+ "test/test_helper.rb",
38
+ "test/test_suite.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/dennijo/sunspot4R}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.6}
44
+ s.summary = %q{Ruby wrapper for DAXKO Sunspot}
45
+ s.test_files = [
46
+ "test/object_service_client_test.rb",
47
+ "test/security_service_client_test.rb",
48
+ "test/system_service_client_test.rb",
49
+ "test/test_helper.rb",
50
+ "test/test_suite.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ s.add_runtime_dependency(%q<savon>, [">= 0.7.8"])
59
+ s.add_runtime_dependency(%q<shoulda>, [">= 0"])
60
+ else
61
+ s.add_dependency(%q<savon>, [">= 0.7.8"])
62
+ s.add_dependency(%q<shoulda>, [">= 0"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<savon>, [">= 0.7.8"])
66
+ s.add_dependency(%q<shoulda>, [">= 0"])
67
+ end
68
+ end
69
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,27 @@
1
+ module Savon
2
+ class Request
3
+
4
+ # FIXME
5
+ # Must add a double quote (") to the soap action for Sunspot to recognize it properly
6
+ def soap_headers
7
+ { "Content-Type" => ContentType[@soap.version], "SOAPAction" => "\"#{@soap.action}\"" }
8
+ end
9
+
10
+ # Returns the Net::HTTP object.
11
+ #
12
+ # Changed the verify mode to "VERIFY_NONE" to get rid of "warning: peer certificate
13
+ # won't be verified in this SSL session" before each request.
14
+ def http
15
+ unless @http
16
+ @http = Net::HTTP::Proxy(@proxy.host, @proxy.port).new @endpoint.host, @endpoint.port
17
+ @http.read_timeout = 300
18
+ @http.ssl_client_auth(:verify_mode => OpenSSL::SSL::VERIFY_NONE)
19
+ end
20
+ @http
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+ # Turning off logging improves performance
27
+ Savon::Request.log = false
data/lib/sunspot4r.rb ADDED
@@ -0,0 +1,23 @@
1
+ # The main Sunspot4R module, serving as a namespace for all Sunspot services.
2
+
3
+ module Sunspot4R
4
+
5
+ NAME = 'SUNSPOT4R'
6
+ VERSION = '0.1'
7
+ USER_AGENT = "%s %s" % [NAME, VERSION]
8
+
9
+ end
10
+
11
+ # Gem dependencies.
12
+ require 'rubygems'
13
+ require 'savon'
14
+ require 'nokogiri'
15
+ require 'shoulda'
16
+
17
+ # Extensions & overrides.
18
+ require 'ext/savon/request'
19
+
20
+ # Core files.
21
+ require 'sunspot4r/system_service_client'
22
+ require 'sunspot4r/security_service_client'
23
+ require 'sunspot4r/object_service_client'
@@ -0,0 +1,77 @@
1
+ module Sunspot4R
2
+
3
+ # = Sunspot4R::BaseSunspotServiceClient
4
+ #
5
+ # Sunspot4R::BaseSunspotServiceClient is service class client that all other
6
+ # Sunspot services extend.
7
+ class BaseSunspotServiceClient < Savon::Client
8
+
9
+ # Name of the Sunspot service. Used to build SOAPAction URLs dynamically.
10
+ def service_name
11
+ '<add service_name>'
12
+ end
13
+
14
+ attr_accessor :base_uri
15
+
16
+ # Optionally pass in the session_guid which will then be placed in the soap
17
+ # package header for each request.
18
+ def initialize(base_url, options = {})
19
+ @session_guid = options.delete(:session_guid)
20
+ endpoint = "#{base_url}/Partner/#{service_name}"
21
+
22
+ super endpoint, options
23
+ #super endpoint, :proxy => 'http://127.0.0.1:8888'
24
+ end
25
+
26
+ private
27
+
28
+ # Same as +super+ but also conveniently enhances a few things:
29
+ # * Capitalizes & adds a base URL to the action
30
+ # * Capitalizes the input
31
+ # * Adds the +xmlns:wsdl+ namespace
32
+ # * Adds SessionIdentifier+ if the +session_guid+ is not nil
33
+ # * Adds the +xmlns:imp+ "Import" namespace
34
+ def setup_objects(action, input, &block)
35
+ super add_base_url_to_action(action), capitalize_first_letter(input), &block
36
+ add_namespace
37
+ add_imports_namespace
38
+ add_session_identifier
39
+ end
40
+
41
+ # Adds the needed base url to the action & captializes the action name so
42
+ # Sunspot will recognize it properly.
43
+ def add_base_url_to_action(action)
44
+ "http://sunspot.arcsolutionsinc.com/Services/I#{service_name}/#{capitalize_first_letter(action)}"
45
+ end
46
+
47
+ # Capitalizes the first letter of a string but leaves everything else the same,
48
+ # unlike string.capitalize which lowercases the rest of the letters in a word.
49
+ # Needed because SOAP actions & inputs CamelCase.
50
+ def capitalize_first_letter(str)
51
+ str.gsub(/^[a-z]/) { |a| a.upcase }
52
+ end
53
+
54
+ # Adds the basic namespace to the SOAP request if one has not already been set.
55
+ def add_namespace
56
+ unless @soap.namespaces.include?("xmlns:wsdl")
57
+ @soap.namespace = 'http://sunspot.arcsolutionsinc.com/Services'
58
+ end
59
+ end
60
+
61
+ # Adds the +xmlns:imp+ to the soap request if the +session_guid+ is not nil.
62
+ def add_imports_namespace
63
+ unless @session_guid.nil? || @soap.nil?
64
+ @soap.namespaces["xmlns:imp"] = "http://sunspot.arcsolutionsinc.com/Services/Imports"
65
+ end
66
+ end
67
+
68
+ # Adds the +imp:SessionIdentifier+ to the soap request if the +session_guid+
69
+ # is not nil.
70
+ def add_session_identifier
71
+ unless @session_guid.nil? || @soap.nil?
72
+ @soap.header = "<imp:SessionIdentifier Id=\"#{@session_guid}\" />"
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,145 @@
1
+ require 'sunspot4r/base_sunspot_service_client'
2
+
3
+ module Sunspot4R
4
+
5
+ # == Sunspot::ObjectServiceClient
6
+ #
7
+ # TODO - Description
8
+ class ObjectServiceClient < BaseSunspotServiceClient
9
+
10
+ # Name of the Sunspot service. Used to build SOAPAction URLs dynamically.
11
+ def service_name
12
+ 'ObjectService'
13
+ end
14
+
15
+ # Returns a list of all Polaris objects accessible to the current user.
16
+ #
17
+ # Response body XML (abbreviated):
18
+ #
19
+ # <GetAvailableObjectsResponse xmlns="http://sunspot.arcsolutionsinc.com/Services">
20
+ # <GetAvailableObjectsResult xmlns:a="http://ARC.Polaris.Sunspot.Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
21
+ # <ApiFaults xmlns="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.API.Results" xmlns:b="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.API"/>
22
+ # <Errors xmlns="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.API.Results" xmlns:b="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.Types"/>
23
+ # <Exception i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.API.Results" xmlns:b="http://schemas.datacontract.org/2004/07/System"/>
24
+ # <Success xmlns="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.API.Results">true</Success>
25
+ # <a:Objects xmlns:b="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.Types">
26
+ # <b:NameValuePair>
27
+ # <b:Name>Advertising Rate</b:Name>
28
+ # <b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">AdvertisingRate</b:Value>
29
+ # </b:NameValuePair>
30
+ # <b:NameValuePair>
31
+ # <b:Name>Career Center Bundle Product</b:Name>
32
+ # <b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">CareerCenterBundleProduct</b:Value>
33
+ # </b:NameValuePair>
34
+ # <b:NameValuePair>
35
+ # <b:Name>Career Center Coupon</b:Name>
36
+ # <b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">CareerCenterCoupon</b:Value>
37
+ # </b:NameValuePair>
38
+ # <b:NameValuePair>
39
+ # <b:Name>Tax Product</b:Name>
40
+ # <b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">TaxProduct</b:Value>
41
+ # </b:NameValuePair>
42
+ # </a:Objects>
43
+ # <a:_objects xmlns:b="http://schemas.datacontract.org/2004/07/ARC.Polaris.Common.Types">
44
+ # <b:NameValuePair>
45
+ # <b:Name>Advertising Rate</b:Name>
46
+ # <b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">AdvertisingRate</b:Value>
47
+ # </b:NameValuePair>
48
+ # <b:NameValuePair>
49
+ # <b:Name>Career Center Bundle Product</b:Name>
50
+ # <b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">CareerCenterBundleProduct</b:Value>
51
+ # </b:NameValuePair>
52
+ # </a:_objects>
53
+ # </GetAvailableObjectsResult>
54
+ # </GetAvailableObjectsResponse>
55
+ def available_objects(association_guid, base_object)
56
+ response = call :get_available_objects! do |soap|
57
+ soap.body = {
58
+ "wsdl:associationGuid" => association_guid,
59
+ "wsdl:baseObject" => base_object,
60
+ :order! => ["wsdl:associationGuid", "wsdl:baseObject"]
61
+ }
62
+ end
63
+ response.to_hash[:get_available_objects_response][:get_available_objects_result]
64
+ end
65
+
66
+ # Loads an object from the system by its GUID.
67
+ #
68
+ # This operation will return either a single object or a null value back.
69
+ # Note that the security placed upon the logged in user is enforced through
70
+ # this operation – if you query an object that your logged in Sunspot
71
+ # account does not have access to, expect an API error to be returned.
72
+ #
73
+ # This operation will return a single PolarisObject that represents the
74
+ # object you are looking for, or null if non were found.
75
+ #
76
+ def query_by_guid(guid)
77
+ response = call :query_by_guid! do |soap|
78
+ soap.body = {
79
+ "wsdl:guid" => guid
80
+ }
81
+ end
82
+ response.to_hash[:query_by_guid_response][:query_by_guid_result]
83
+ end
84
+
85
+ # #Upsert #Saves an object into the system, inserting it if it does not
86
+ # exist and updating it if it does. #This is your general purpose
87
+ # SaveOrUpdate operation that determines whether or not the object #exists
88
+ # and updates it if it does, inserts it if it doesn’t. The system uses the
89
+ # read-only #RepositoryKey property of the PolarisObject to determine
90
+ # whether or not it exists in the system. #This operation will return an
91
+ # updated version of the object that was saved. If the object was new, #then
92
+ # this updated version will contain the generated GUID and any other
93
+ # automatically generated information.
94
+ def upsert
95
+
96
+ end
97
+
98
+ def describe_object(association_guid, base_object)
99
+ response = call :describe_p_object! do |soap|
100
+ soap.body = {
101
+ "wsdl:associationGuid" => association_guid,
102
+ "wsdl:objectName" => base_object,
103
+ :order! => ["wsdl:associationGuid", "wsdl:objectName"]
104
+ }
105
+ end
106
+ response.to_hash[:describe_p_object_response][:describe_p_object_result]
107
+ end
108
+
109
+ def get_all(association_guid, base_object)
110
+ response = call :get_all! do |soap|
111
+ soap.body = {
112
+ "wsdl:associationGuid" => association_guid,
113
+ "wsdl:objectName" => base_object,
114
+ :order! => ["wsdl:associationGuid", "wsdl:objectName"]
115
+ }
116
+ end
117
+ response.to_hash[:get_all_response][:get_all_result]
118
+ end
119
+
120
+ def query(association_guid, query, first = nil, max = nil)
121
+ unless first.nil? || max.nil?
122
+ response = call :query! do |soap|
123
+ soap.body = {
124
+ "wsdl:associationGuid" => association_guid,
125
+ "wsdl:query" => query,
126
+ "wsdl:firstResult" => first,
127
+ "wsdl:maxResults" => max,
128
+ :order! => ["wsdl:associationGuid", "wsdl:query", "wsdl:firstResult", "wsdl:maxResults"]
129
+ }
130
+ end
131
+ else
132
+ response = call :query! do |soap|
133
+ soap.body = {
134
+ "wsdl:associationGuid" => association_guid,
135
+ "wsdl:query" => query,
136
+ :order! => ["wsdl:associationGuid", "wsdl:query"]
137
+ }
138
+ end
139
+ end
140
+ response.to_hash[:query_response][:query_result]
141
+ #response.to_xml
142
+ end
143
+ end
144
+
145
+ end