google-ads-common 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ #
5
+ # Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
6
+ #
7
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Handles soap headers for AdWords v2009-style SOAP requests (nested headers).
21
+
22
+ require 'soap/header/simplehandler'
23
+
24
+ module AdsCommon
25
+ module Soap4rHeaders
26
+
27
+ class NestedHeaderHandler < SOAP::Header::SimpleHandler
28
+
29
+ def initialize(credential_handler, auth_handler, top_element_name,
30
+ top_namespace, inner_namespace, version = nil)
31
+ super(XSD::QName.new(top_namespace, top_element_name))
32
+ @credential_handler = credential_handler
33
+ @auth_handler = auth_handler
34
+ @ns = inner_namespace
35
+ @version = version
36
+ end
37
+
38
+ # Handles callback.
39
+ def on_simple_outbound
40
+ main_header = SOAP::SOAPElement.new(nil)
41
+ credentials = @credential_handler.credentials(@version)
42
+ @auth_handler.headers(credentials).each do |cred, value|
43
+ cred_header = SOAP::SOAPElement.new(XSD::QName.new(@ns, cred), value)
44
+ main_header.add(cred_header)
45
+ end
46
+ return main_header
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ #
5
+ # Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
6
+ #
7
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Handles soap headers for AdWords v13-style SOAP requests (flat headers).
21
+
22
+ require 'soap/header/simplehandler'
23
+
24
+ module AdsCommon
25
+ module Soap4rHeaders
26
+
27
+ class SingleHeaderHandler < SOAP::Header::SimpleHandler
28
+
29
+ def initialize(credential_handler, auth_handler,
30
+ element_name, element_namespace = nil, version = nil)
31
+ super(XSD::QName.new(element_namespace, element_name))
32
+ @credential_handler = credential_handler
33
+ @auth_handler = auth_handler
34
+ @element_name = element_name
35
+ @version = version
36
+ end
37
+
38
+ def on_simple_outbound
39
+ credentials = @credential_handler.credentials(@version)
40
+ return @auth_handler.headers(credentials)[@element_name]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ # api.jeffy@gmail.com (Jeffrey Posnick)
5
+ #
6
+ # Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
7
+ #
8
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
17
+ # implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ #
21
+ # Collection of small patches to soap4r, used in the client libraries.
22
+
23
+ require 'rubygems'
24
+ begin
25
+ gem 'soap4r', '=1.5.8'
26
+ rescue
27
+ require_gem 'soap4r', '=1.5.8'
28
+ end
29
+ require 'soap/soap'
30
+ require 'soap/rpc/driver'
31
+
32
+
33
+ # Fix an issue with code generation: the infamous "type collapse" bug. This
34
+ # should avoid objects with just one property, that happens to be an array, from
35
+ # being collapsed into a simple array.
36
+ module WSDL
37
+ module SOAP
38
+ class ClassDefCreator
39
+ def dump_complextype
40
+ definitions = sort_dependency(@complextypes).collect { |type|
41
+ c = create_complextypedef(@modulepath, type.name, type)
42
+ c ? c.dump : nil
43
+ }.compact.join("\n")
44
+ end
45
+
46
+ def create_complextypedef(mpath, qname, type, qualified = false)
47
+ case type.compoundtype
48
+ when :TYPE_STRUCT, :TYPE_EMPTY
49
+ create_structdef(mpath, qname, type, qualified)
50
+ when :TYPE_ARRAY
51
+ ### Patch starts here ###
52
+ create_structdef(mpath, qname, type, qualified)
53
+ #create_arraydef(mpath, qname, type)
54
+ ### Patch ends here ###
55
+ when :TYPE_SIMPLE
56
+ create_simpleclassdef(mpath, qname, type)
57
+ when :TYPE_MAP
58
+ # mapped as a general Hash
59
+ nil
60
+ else
61
+ raise RuntimeError.new(
62
+ "unknown kind of complexContent: #{type.compoundtype}")
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ module SOAP
70
+
71
+ # Fix an issue with SOAPDate. Google complains if the dates have any timezone
72
+ # info in them. There are probably better ways to fix this.
73
+ class SOAPDate
74
+
75
+ def of2tz(offset)
76
+ diffmin = offset * 24 * 60
77
+ if diffmin.zero?
78
+ ''
79
+ else
80
+ ((diffmin < 0) ? '-' : '+') << format('%02d:%02d',
81
+ (diffmin.abs / 60.0).to_i, (diffmin.abs % 60.0).to_i)
82
+ end
83
+ end
84
+ end
85
+
86
+ # Fix an issue with base64 encoded items in responses, which causes them to
87
+ # be encoded twice
88
+ module Mapping
89
+ class LiteralRegistry
90
+ def base2obj(value, klass)
91
+ v = if value.respond_to?(:data)
92
+ value.data
93
+ elsif value.respond_to?(:text)
94
+ value.text
95
+ else
96
+ nil
97
+ end
98
+ ### Patch starts here ###
99
+ if klass.to_s == 'SOAP::SOAPBase64'
100
+ v
101
+ ### Patch ends here ###
102
+ elsif value.is_a?(klass)
103
+ v
104
+ else
105
+ klass.to_data(v)
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ # Monkey-patching soap4r to add a callback at the Proxy level. Not exactly the
112
+ # prettiest way of doing things, but other callback levels in soap4r don't
113
+ # provide all the information we need to log.
114
+ module RPC
115
+
116
+ class CallbackHandler
117
+
118
+ # The callback handler takes a method name (the API method invoked), an
119
+ # endpoint and the message envelope. This method is meant to be overloaded
120
+ # in derived classes.
121
+ def on_callback(method_name, endpoint, envelope)
122
+ return nil
123
+ end
124
+ end
125
+
126
+ class Driver
127
+ # Use the Driver class's __attr_proxy method to declare getters and
128
+ # setters for "callbackhandler". These reference the getters and setters
129
+ # for the property with the same name in the Proxy object contained
130
+ # within driver (@proxy).
131
+ __attr_proxy :callbackhandler, true
132
+
133
+ end
134
+
135
+ class Proxy
136
+
137
+ attr_accessor :callbackhandler
138
+
139
+ # This method is a copy of the one included in soap4r, with the additions
140
+ # marked below, to enable the callback.
141
+ def call(name, *params)
142
+ # name must be used only for lookup
143
+ op_info = lookup_operation(name)
144
+ mapping_opt = create_mapping_opt
145
+ req_header = create_request_header
146
+ req_body = SOAPBody.new(
147
+ op_info.request_body(params, @mapping_registry,
148
+ @literal_mapping_registry, mapping_opt)
149
+ )
150
+ reqopt = create_encoding_opt(
151
+ :soapaction => op_info.soapaction || @soapaction,
152
+ :envelopenamespace => @options["soap.envelope.requestnamespace"],
153
+ :default_encodingstyle =>
154
+ @default_encodingstyle || op_info.request_default_encodingstyle,
155
+ :use_default_namespace =>
156
+ op_info.use_default_namespace || @use_default_namespace
157
+ )
158
+ resopt = create_encoding_opt(
159
+ :envelopenamespace => @options["soap.envelope.responsenamespace"],
160
+ :default_encodingstyle =>
161
+ @default_encodingstyle || op_info.response_default_encodingstyle
162
+ )
163
+ if reqopt[:generate_explicit_type].nil?
164
+ reqopt[:generate_explicit_type] = (op_info.request_use == :encoded)
165
+ end
166
+ if resopt[:generate_explicit_type].nil?
167
+ resopt[:generate_explicit_type] = (op_info.response_use == :encoded)
168
+ end
169
+ env = route(req_header, req_body, reqopt, resopt)
170
+ ### Patch starts here ###
171
+ if op_info.response_use.nil?
172
+ unless callbackhandler.nil?
173
+ callbackhandler.on_callback(name, @endpoint_url, env, params)
174
+ end
175
+ return nil
176
+ end
177
+ fault = false
178
+ fault_message = nil
179
+ begin
180
+ unless env
181
+ fault = true
182
+ fault_message = 'Empty SOAP response'
183
+ raise EmptyResponseError
184
+ end
185
+ receive_headers(env.header)
186
+ begin
187
+ check_fault(env.body)
188
+ rescue ::SOAP::FaultError => e
189
+ fault = true
190
+ fault_message = e.to_s
191
+ op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)
192
+ end
193
+ ensure
194
+ unless callbackhandler.nil?
195
+ callbackhandler.on_callback(name, @endpoint_url, env, params, fault,
196
+ fault_message)
197
+ end
198
+ end
199
+ ### Patch ends here ###
200
+
201
+ if @return_response_as_xml
202
+ resopt[:response_as_xml]
203
+ else
204
+ op_info.response_obj(env.body, @mapping_registry,
205
+ @literal_mapping_registry, mapping_opt)
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ #
5
+ # Copyright:: Copyright 2010, Google Inc. All Rights Reserved.
6
+ #
7
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Generic callback handling class, to be inherited from and extended for
21
+ # specific APIs.
22
+
23
+ require 'ads_common/soap4r_patches'
24
+
25
+ module AdsCommon
26
+
27
+ # Handler class to process response messages for API unit usage and statistics
28
+ # information.
29
+ class Soap4rResponseHandler < SOAP::RPC::CallbackHandler
30
+
31
+ # Constructor for Soap4rResponseHandler.
32
+ #
33
+ # Args:
34
+ # - parent: AdsCommon::Api object to which this instance should be tied
35
+ #
36
+ def initialize(parent)
37
+ @parent = parent
38
+ end
39
+
40
+ # Handles the callback method.
41
+ # This method is a prime candidate for redefinition in specific APIs.
42
+ #
43
+ # Args:
44
+ # - method_name: name for the operation that was invoked
45
+ # - endpoint: the endpoint URL the request was sent to
46
+ # - envelope: the envelope for the SOAP response that was received
47
+ # - params: the parameters that were passed to the method
48
+ # - fault: whether the request resulted in a fault or not
49
+ # - fault_msg: the fault message in case of a fault (nil if none)
50
+ #
51
+ def on_callback(method_name, endpoint, envelope, params, fault = false,
52
+ fault_msg = nil)
53
+
54
+ host = URI.parse(endpoint).host
55
+
56
+ data = "host=#{host} method=#{method_name} "
57
+ data += "isFault=#{(!!fault).to_s} "
58
+
59
+ if fault_msg
60
+ data += "faultMessage=\"#{fault_msg}\""
61
+ else
62
+ data += "faultMessage=none"
63
+ end
64
+
65
+ @parent.request_logger << data
66
+ end
67
+
68
+ # Parses the value contained in a SOAP response header.
69
+ #
70
+ # Args:
71
+ # - header: an object representing a SOAP header
72
+ #
73
+ # Returns:
74
+ # The value contained in the header as a string, or nil if the header is nil
75
+ #
76
+ def parse_header(header)
77
+ if header.nil?
78
+ return nil
79
+ end
80
+
81
+ header_element = header
82
+ if header.instance_variable_defined?('@element')
83
+ header_element = header.element
84
+ end
85
+
86
+ return header_element.text
87
+ end
88
+ end
89
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google-ads-common
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Sergio Gomes
14
+ - Danial Klimkin
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-03-16 00:00:00 +00:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: soap4r
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - "="
29
+ - !ruby/object:Gem::Version
30
+ hash: 19
31
+ segments:
32
+ - 1
33
+ - 5
34
+ - 8
35
+ version: 1.5.8
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: httpclient
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 119
47
+ segments:
48
+ - 2
49
+ - 1
50
+ - 5
51
+ - 2
52
+ version: 2.1.5.2
53
+ type: :runtime
54
+ version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: httpi
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ hash: 17
64
+ segments:
65
+ - 0
66
+ - 7
67
+ - 9
68
+ version: 0.7.9
69
+ type: :runtime
70
+ version_requirements: *id003
71
+ description: ads_common provides essential utilities shared by all Ads Ruby client libraries.
72
+ email: api.sgomes@gmail.com
73
+ executables: []
74
+
75
+ extensions: []
76
+
77
+ extra_rdoc_files:
78
+ - README
79
+ files:
80
+ - Rakefile
81
+ - lib/ads_common/auth/base_handler.rb
82
+ - lib/ads_common/auth/client_login_handler.rb
83
+ - lib/ads_common/build/rake_common.rb
84
+ - lib/ads_common/build/savon_abstract_generator.rb
85
+ - lib/ads_common/build/savon_generator.rb
86
+ - lib/ads_common/build/savon_registry.rb
87
+ - lib/ads_common/build/savon_registry_generator.rb
88
+ - lib/ads_common/build/savon_service_generator.rb
89
+ - lib/ads_common/build/soap4r_generator.rb
90
+ - lib/ads_common/savon_headers/simple_header_handler.rb
91
+ - lib/ads_common/soap4r_headers/nested_header_handler.rb
92
+ - lib/ads_common/soap4r_headers/single_header_handler.rb
93
+ - lib/ads_common/api.rb
94
+ - lib/ads_common/api_config.rb
95
+ - lib/ads_common/config.rb
96
+ - lib/ads_common/credential_handler.rb
97
+ - lib/ads_common/errors.rb
98
+ - lib/ads_common/http.rb
99
+ - lib/ads_common/logger.rb
100
+ - lib/ads_common/soap4r_patches.rb
101
+ - lib/ads_common/soap4r_response_handler.rb
102
+ - README
103
+ has_rdoc: true
104
+ homepage: http://code.google.com/p/google-api-adwords-ruby/
105
+ licenses: []
106
+
107
+ post_install_message:
108
+ rdoc_options:
109
+ - --main
110
+ - README
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements:
132
+ - soap4r v1.5.8
133
+ - httpclient v2.1.5.2 or greater
134
+ - httpi v0.7.9 or greater
135
+ rubyforge_project: google-ads-common
136
+ rubygems_version: 1.6.2
137
+ signing_key:
138
+ specification_version: 3
139
+ summary: Common code for Google Ads APIs.
140
+ test_files: []
141
+