adwords4r 13.0.1 → 15.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/Authors.txt +2 -1
  2. data/ChangeLog.txt +28 -0
  3. data/Copying.txt +1 -1
  4. data/{Licence.txt → License.txt} +1 -1
  5. data/Rakefile +49 -54
  6. data/Readme.txt +78 -24
  7. data/adwords.properties +1 -1
  8. data/examples/account_info.rb +20 -26
  9. data/examples/create_all.rb +51 -53
  10. data/examples/create_all_v200902.rb +204 -0
  11. data/examples/keyword_suggestions.rb +35 -38
  12. data/examples/multiple_versions.rb +167 -0
  13. data/examples/reports.rb +37 -75
  14. data/lib/adwords4r.rb +123 -123
  15. data/lib/adwords4r/adwordslogger.rb +56 -0
  16. data/lib/adwords4r/apiextensions.rb +79 -0
  17. data/lib/adwords4r/authtoken.rb +56 -0
  18. data/lib/adwords4r/credentials.rb +115 -19
  19. data/lib/adwords4r/services.rb +139 -14
  20. data/lib/adwords4r/soap4rpatches.rb +129 -0
  21. data/lib/adwords4r/v13/AccountService.rb +11 -11
  22. data/lib/adwords4r/v13/AccountServiceDriver.rb +7 -5
  23. data/lib/adwords4r/v13/AccountServiceMappingRegistry.rb +56 -56
  24. data/lib/adwords4r/v13/AdGroupService.rb +9 -9
  25. data/lib/adwords4r/v13/AdGroupServiceDriver.rb +11 -9
  26. data/lib/adwords4r/v13/AdGroupServiceMappingRegistry.rb +47 -47
  27. data/lib/adwords4r/v13/AdService.rb +37 -37
  28. data/lib/adwords4r/v13/AdServiceDriver.rb +12 -10
  29. data/lib/adwords4r/v13/AdServiceMappingRegistry.rb +148 -148
  30. data/lib/adwords4r/v13/CampaignService.rb +46 -25
  31. data/lib/adwords4r/v13/CampaignServiceDriver.rb +23 -13
  32. data/lib/adwords4r/v13/CampaignServiceMappingRegistry.rb +169 -135
  33. data/lib/adwords4r/v13/CriterionService.rb +19 -19
  34. data/lib/adwords4r/v13/CriterionServiceDriver.rb +11 -9
  35. data/lib/adwords4r/v13/CriterionServiceMappingRegistry.rb +90 -90
  36. data/lib/adwords4r/v13/InfoService.rb +3 -3
  37. data/lib/adwords4r/v13/InfoServiceDriver.rb +10 -8
  38. data/lib/adwords4r/v13/InfoServiceMappingRegistry.rb +29 -29
  39. data/lib/adwords4r/v13/KeywordToolService.rb +10 -10
  40. data/lib/adwords4r/v13/KeywordToolServiceDriver.rb +4 -2
  41. data/lib/adwords4r/v13/KeywordToolServiceMappingRegistry.rb +37 -37
  42. data/lib/adwords4r/v13/ReportService.rb +13 -13
  43. data/lib/adwords4r/v13/ReportServiceDriver.rb +9 -7
  44. data/lib/adwords4r/v13/ReportServiceMappingRegistry.rb +54 -54
  45. data/lib/adwords4r/v13/SiteSuggestionService.rb +15 -15
  46. data/lib/adwords4r/v13/SiteSuggestionServiceDriver.rb +6 -4
  47. data/lib/adwords4r/v13/SiteSuggestionServiceMappingRegistry.rb +57 -57
  48. data/lib/adwords4r/v13/TrafficEstimatorService.rb +17 -17
  49. data/lib/adwords4r/v13/TrafficEstimatorServiceDriver.rb +6 -4
  50. data/lib/adwords4r/v13/TrafficEstimatorServiceMappingRegistry.rb +96 -96
  51. data/lib/adwords4r/v200902/AdGroupAdService.rb +2021 -0
  52. data/lib/adwords4r/v200902/AdGroupAdServiceDriver.rb +63 -0
  53. data/lib/adwords4r/v200902/AdGroupAdServiceMappingRegistry.rb +2234 -0
  54. data/lib/adwords4r/v200902/AdGroupCriterionService.rb +1209 -0
  55. data/lib/adwords4r/v200902/AdGroupCriterionServiceDriver.rb +63 -0
  56. data/lib/adwords4r/v200902/AdGroupCriterionServiceMappingRegistry.rb +1434 -0
  57. data/lib/adwords4r/v200902/AdGroupService.rb +968 -0
  58. data/lib/adwords4r/{v12/KeywordToolServiceDriver.rb → v200902/AdGroupServiceDriver.rb} +15 -13
  59. data/lib/adwords4r/v200902/AdGroupServiceMappingRegistry.rb +1114 -0
  60. data/lib/adwords4r/v200902/CampaignCriterionService.rb +741 -0
  61. data/lib/adwords4r/v200902/CampaignCriterionServiceDriver.rb +63 -0
  62. data/lib/adwords4r/v200902/CampaignCriterionServiceMappingRegistry.rb +904 -0
  63. data/lib/adwords4r/v200902/CampaignService.rb +1249 -0
  64. data/lib/adwords4r/v200902/CampaignServiceDriver.rb +63 -0
  65. data/lib/adwords4r/v200902/CampaignServiceMappingRegistry.rb +1466 -0
  66. data/lib/adwords4r/v200902/CampaignTargetService.rb +1156 -0
  67. data/lib/adwords4r/v200902/CampaignTargetServiceDriver.rb +63 -0
  68. data/lib/adwords4r/v200902/CampaignTargetServiceMappingRegistry.rb +1304 -0
  69. data/setup.rb +0 -0
  70. metadata +57 -65
  71. data/lib/adwords4r/v12/AccountService.rb +0 -215
  72. data/lib/adwords4r/v12/AccountServiceDriver.rb +0 -69
  73. data/lib/adwords4r/v12/AccountServiceMappingRegistry.rb +0 -243
  74. data/lib/adwords4r/v12/AdGroupService.rb +0 -263
  75. data/lib/adwords4r/v12/AdGroupServiceDriver.rb +0 -109
  76. data/lib/adwords4r/v12/AdGroupServiceMappingRegistry.rb +0 -280
  77. data/lib/adwords4r/v12/AdService.rb +0 -769
  78. data/lib/adwords4r/v12/AdServiceDriver.rb +0 -125
  79. data/lib/adwords4r/v12/AdServiceMappingRegistry.rb +0 -813
  80. data/lib/adwords4r/v12/CampaignService.rb +0 -498
  81. data/lib/adwords4r/v12/CampaignServiceDriver.rb +0 -133
  82. data/lib/adwords4r/v12/CampaignServiceMappingRegistry.rb +0 -642
  83. data/lib/adwords4r/v12/CriterionService.rb +0 -445
  84. data/lib/adwords4r/v12/CriterionServiceDriver.rb +0 -117
  85. data/lib/adwords4r/v12/CriterionServiceMappingRegistry.rb +0 -509
  86. data/lib/adwords4r/v12/InfoService.rb +0 -242
  87. data/lib/adwords4r/v12/InfoServiceDriver.rb +0 -109
  88. data/lib/adwords4r/v12/InfoServiceMappingRegistry.rb +0 -228
  89. data/lib/adwords4r/v12/KeywordToolService.rb +0 -205
  90. data/lib/adwords4r/v12/KeywordToolServiceMappingRegistry.rb +0 -227
  91. data/lib/adwords4r/v12/ReportService.rb +0 -322
  92. data/lib/adwords4r/v12/ReportServiceDriver.rb +0 -101
  93. data/lib/adwords4r/v12/ReportServiceMappingRegistry.rb +0 -298
  94. data/lib/adwords4r/v12/SiteSuggestionService.rb +0 -242
  95. data/lib/adwords4r/v12/SiteSuggestionServiceDriver.rb +0 -77
  96. data/lib/adwords4r/v12/SiteSuggestionServiceMappingRegistry.rb +0 -271
  97. data/lib/adwords4r/v12/TrafficEstimatorService.rb +0 -312
  98. data/lib/adwords4r/v12/TrafficEstimatorServiceDriver.rb +0 -77
  99. data/lib/adwords4r/v12/TrafficEstimatorServiceMappingRegistry.rb +0 -483
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Copyright 2009, Google Inc. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # Wrapper class to handle logging to console and/or files.
18
+
19
+ require 'logger'
20
+
21
+ module AdWords
22
+
23
+ class AdWordsLogger
24
+
25
+ def initialize(filename, log_to_console=false)
26
+ @filename = filename
27
+ @loggers = []
28
+ if log_to_console
29
+ stderr_logger = Logger.new(STDERR)
30
+ stderr_logger.level = Logger::INFO
31
+ @loggers << stderr_logger
32
+ end
33
+ end
34
+
35
+ # Enables logging to a file (path optional)
36
+ def log_to_file(path=".#{File::SEPARATOR}")
37
+ if path[-1, 1] == File::SEPARATOR
38
+ normalized_path = path
39
+ else
40
+ normalized_path = path + File::SEPARATOR
41
+ end
42
+ new_logger = Logger.new(normalized_path + @filename)
43
+ new_logger.level = Logger::INFO
44
+ @loggers << new_logger
45
+
46
+ return nil
47
+ end
48
+
49
+ # Overload << operator to perform logging
50
+ def << (text)
51
+ @loggers.each do |logger|
52
+ logger.info text
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Copyright 2009, Google Inc. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # Contains extensions to the API, that is, service helper methods provided in
18
+ # client-side by the client library.
19
+
20
+ module AdWords
21
+
22
+ module Extensions
23
+
24
+ # Maintains a list of all extensions, indexed by version and service
25
+ # Using camelCase to match API method names
26
+ @@extensions = {
27
+ [13, 'Report'] => ['downloadXmlReport']
28
+ }
29
+
30
+ # Defines the parameter list for every extension method
31
+ @@methods = {
32
+ 'downloadXmlReport' => ['job_id']
33
+ }
34
+
35
+ def self.extensions
36
+ return @@extensions
37
+ end
38
+
39
+ def self.methods
40
+ return @@methods
41
+ end
42
+
43
+ # Download and return report data in XML format.
44
+ # Warning: this method is blocking for the calling thread.
45
+ def self.downloadXmlReport(wrapper, job_id)
46
+ sleep_interval = 30
47
+
48
+ # Repeatedly check the report status until it is finished.
49
+ # 'Pending' and 'InProgress' statuses indicate the job is still being run.
50
+ status = wrapper.getReportJobStatus(job_id).getReportJobStatusReturn
51
+ while status != 'Completed' && status != 'Failed'
52
+ sleep(sleep_interval)
53
+ status = wrapper.getReportJobStatus(job_id).getReportJobStatusReturn
54
+ end
55
+
56
+ if status == 'Completed'
57
+ report_url =
58
+ wrapper.getReportDownloadUrl(job_id).getReportDownloadUrlReturn
59
+
60
+ # Download the report via the HTTPClient library and return its
61
+ # contents. The report is an XML document; the actual element names vary
62
+ # depending on the type of report run and columns requested.
63
+ begin
64
+ client = HTTPClient.new
65
+ return client.get_content(report_url)
66
+ rescue Errno::ECONNRESET, SOAP::HTTPStreamError, SocketError => e
67
+ # This exception indicates a connection-level error.
68
+ # In general, it is likely to be transitory.
69
+ raise AdWords::Error::Error, "Connection Error: %s\nSource: %s" %
70
+ [e, e.backtrace.first]
71
+ end
72
+ else
73
+ # Reports that pass validation will normally not fail, but if there is
74
+ # an error in the report generation service it can sometimes happen.
75
+ raise AdWords::Error::Error, 'Report generation failed.'
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Copyright 2009, Google Inc. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # This library connects to Google's ClientLogin service and generates an
18
+ # AuthToken that can be used to login to the AdWords API.
19
+
20
+ require 'cgi'
21
+ require 'net/http'
22
+ require 'net/https'
23
+
24
+ module AdWords
25
+
26
+ class AuthToken
27
+
28
+ ACCOUNT_TYPE = 'GOOGLE'
29
+ AUTH_HOSTNAME = 'www.google.com'
30
+ AUTH_PATH = '/accounts/ClientLogin'
31
+ AUTH_PORT = 443
32
+ SERVICE = 'adwords'
33
+
34
+ def self.get_token(email, password)
35
+ email = CGI.escape(email)
36
+ password = CGI.escape(password)
37
+
38
+ http_client = Net::HTTP.new(AUTH_HOSTNAME, AUTH_PORT)
39
+ http_client.use_ssl = true
40
+
41
+ data = "accountType=#{ACCOUNT_TYPE}&Email=#{email}&Passwd=#{password}" +
42
+ "&service=#{SERVICE}"
43
+ headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
44
+
45
+ response = http_client.post(AUTH_PATH, data, headers)
46
+
47
+ if response.code == '200'
48
+ return response.body[/Auth=(.*)/, 1]
49
+ else
50
+ raise AdWords::Error::AuthError,
51
+ "Login failed for email %s: %s (code %d)" %
52
+ [CGI.unescape(email), response.message, response.code]
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,56 +1,152 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Copyright 2009, Google Inc. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # Handles credentials for the SOAP requests, for both <= v13 and >= v200902.
18
+
1
19
  require 'soap/header/simplehandler'
20
+ require 'adwords4r/authtoken'
2
21
 
3
22
  module AdWords
4
23
 
5
- class HeaderHandler < SOAP::Header::SimpleHandler
24
+ # Handles the headers used in the v200902 sandbox requests
25
+ class Sandbox200902HeaderHandler < SOAP::Header::SimpleHandler
26
+
27
+ # Receives an AdWordsCredentials object as parent
28
+ def initialize(parent)
29
+ namespace = 'https://adwords.google.com/api/adwords/cm/v200902'
30
+ super(XSD::QName.new(namespace, 'RequestHeader'))
31
+ @parent = parent
32
+ end
33
+
34
+ def on_simple_outbound
35
+ return { :authToken => @parent.auth_token,
36
+ :clientEmail => @parent.credentials['clientEmail'] }
37
+ end
38
+ end
39
+
40
+ # Handles the headers used in <= v13 (both sandbox and production)
41
+ class Pre200902HeaderHandler < SOAP::Header::SimpleHandler
42
+
6
43
  attr_reader :tag
7
44
  attr_writer :value
8
45
 
46
+ # Receives a tag name (email, password, etc.) and a value to be sent in that
47
+ # tag for outgoing requests
9
48
  def initialize(tag, value)
10
49
  super(XSD::QName.new(nil, tag))
11
50
  @tag = tag
12
51
  @value = value
13
52
  end
14
53
 
15
- #the initial handler from the sample was wrong, it generated 2 level of tags
16
54
  def on_simple_outbound
17
55
  @value
18
56
  end
19
57
  end
20
58
 
59
+ # Generic credentials class, used for any API version
21
60
  class AdWordsCredentials
22
- attr_reader :handlers, :alternateUrl
23
61
 
24
- def getDefaults()
25
- cred = Hash.new
26
- IO.foreach("#{ENV['HOME']}/adwords.properties") {|line|
27
- addCredential(cred, line.split('=')) if !(line =~ /^#/)}
28
- return cred
29
- end
62
+ attr_reader :credentials, :alternateUrl
30
63
 
31
- def addCredential(cred, arr)
32
- cred[arr[0]] = arr[1].strip
33
- end
64
+ public
34
65
 
35
66
  def initialize(*parm)
36
- @handlers = []
67
+ @credentials = {}
37
68
  @alternateUrl = nil
38
- if parm[0]
69
+ @auth_token = nil
70
+ @handlers = []
71
+ if parm[0]
39
72
  credentials = parm[0]
40
73
  else
41
- credentials = getDefaults()
74
+ credentials = get_defaults()
75
+ end
76
+ credentials.each do |key, value|
77
+ @credentials[key] = value if !(key =~ /^alternateUrl/)
42
78
  end
43
- credentials.each {|key, value|
44
- @handlers << HeaderHandler.new(key, value) if !(key =~ /^alternateUrl/)}
45
79
  @alternateUrl = credentials['alternateUrl']
80
+ @credentials.each do |key, value|
81
+ @handlers << Pre200902HeaderHandler.new(key, value)
82
+ end
83
+ end
84
+
85
+ # Return a list of handlers to be inserted into the driver's handler list
86
+ def get_handlers(version)
87
+ if (version <= 13)
88
+ return @handlers
89
+ else
90
+ return [Sandbox200902HeaderHandler.new(self)]
91
+ end
46
92
  end
47
93
 
48
- def setHeader(header, value)
49
- handlers.each do |handler|
94
+ # Returns the authentication token used with >= v200902 requests
95
+ def auth_token
96
+ generate_auth_token if @auth_token.nil?
97
+ return @auth_token
98
+ end
99
+
100
+ # Generates a new authentication token used with >= v200902 requests
101
+ # (should only be necessary for user code to invoke this if the first token
102
+ # expires)
103
+ def generate_auth_token
104
+ email = @credentials['email']
105
+ password = @credentials['password']
106
+
107
+ if email.nil?
108
+ raise AdWords::Error::AuthError,
109
+ 'Email address not included in credentials.'
110
+ end
111
+
112
+ if password.nil?
113
+ raise AdWords::Error::AuthError, 'Password not included in credentials.'
114
+ end
115
+
116
+ @auth_token = AdWords::AuthToken::get_token(email, password)
117
+ return @auth_token
118
+ end
119
+
120
+ # Changes one of the headers
121
+ def set_header(header, value)
122
+ # Invalidate previous auth token if necessary
123
+ @auth_token = nil if header == 'email' or header == 'password'
124
+
125
+ @credentials.each_key do |key|
126
+ if key == header then
127
+ @credentials[key] = value
128
+ end
129
+ end
130
+
131
+ @handlers.each do |handler|
50
132
  if handler.tag == header then
51
133
  handler.value = value
52
134
  end
53
135
  end
54
136
  end
137
+
138
+ private
139
+
140
+ def get_defaults
141
+ cred = Hash.new
142
+ IO.foreach("#{ENV['HOME']}/adwords.properties") do |line|
143
+ add_credential(cred, line.split('=')) if !(line =~ /^#/)
144
+ end
145
+ return cred
146
+ end
147
+
148
+ def add_credential(cred, arr)
149
+ cred[arr[0]] = arr[1].strip
150
+ end
55
151
  end
56
152
  end
@@ -1,31 +1,156 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Copyright 2009, Google Inc. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # Helper methods for loading and managing the available services
18
+
1
19
  module AdWords
20
+
2
21
  class Service
3
22
 
4
- @services = {
5
- 12 => ["Account", "AdGroup", "Ad", "Campaign", "Criterion", "Info",
6
- "KeywordTool", "Report", "SiteSuggestion", "TrafficEstimator"],
23
+ @@services = {
7
24
  13 => ["Account", "AdGroup", "Ad", "Campaign", "Criterion", "Info",
8
- "KeywordTool", "Report", "SiteSuggestion", "TrafficEstimator"]
25
+ "KeywordTool", "Report", "SiteSuggestion", "TrafficEstimator"],
26
+ 200902 => ["AdGroupAd", "AdGroupCriterion", "AdGroup",
27
+ "CampaignCriterion", "Campaign", "CampaignTarget"]
9
28
  }
10
29
 
11
- def self.getVersions
12
- @services.keys
30
+ public
31
+
32
+ # Get the available API versions
33
+ def self.get_versions
34
+ @@services.keys
13
35
  end
14
36
 
15
- def self.getServices(version)
16
- @services[version]
37
+ # Get the list of service names for a given version
38
+ def self.get_services(version)
39
+ @@services[version]
17
40
  end
18
41
 
19
- def self.doRequire(version)
20
- getServices(version).each do |s|
42
+ # Perform the loading of the necessary source files for a version
43
+ def self.do_require(version)
44
+ get_services(version).each do |s|
21
45
  eval("require 'adwords4r/v#{version}/#{s}ServiceDriver'")
22
46
  end
23
47
  end
24
48
 
25
- def self.getMethodMap(drivers)
26
- methodMap = Hash.new
27
- drivers.each_value {|d| d.class::Methods.each {|m| methodMap[m[1]] = d}}
28
- return methodMap
49
+ # Generate the wrapper class for a given service.
50
+ # These classes make it easier to invoke the API methods, by removing the
51
+ # need to instance a <MethodName> object, instead allowing passing of the
52
+ # call parameters directly.
53
+ # Here is an example of a generated wrapper, with one API method and one
54
+ # extension:
55
+ # class SampleServiceWrapper
56
+ #
57
+ # def initialize(driver)
58
+ # @driver = driver
59
+ # end
60
+ #
61
+ # def getSomething(*arg)
62
+ # begin
63
+ # obj = AdWords::V13::GetSomething.new(*arg)
64
+ # return @driver.getSomething(obj)
65
+ # rescue SOAP::FaultError => fault
66
+ # raise (Error::ApiError.new(fault),
67
+ # "getSomething Call Failed: " + fault.faultstring.to_s, caller)
68
+ # end
69
+ # end
70
+ #
71
+ # def doSomethingElseExtension(par1, par2)
72
+ # return AdWords::Extensions.doSomethingElseExtension(self, par1, par2)
73
+ # end
74
+ # end
75
+ def self.generate_wrapper_class(version, service)
76
+ wrapper = service + "ServiceWrapper"
77
+
78
+ mod = eval(get_module_name(version, service))
79
+
80
+ unless mod.const_defined? wrapper # Avoid double initialization
81
+ driver = eval(get_interface_name(version, service))
82
+ class_def = <<-EOS
83
+ class #{wrapper}
84
+ def initialize(driver)
85
+ @driver = driver
86
+ end
87
+ EOS
88
+
89
+ # Add service methods
90
+ methods = driver::Methods
91
+ module_name = get_module_name(version, service)
92
+ methods.each do |method|
93
+ name = method[1]
94
+ method_def = <<-EOS
95
+ def #{name}(*arg)
96
+ begin
97
+ obj = #{module_name}::#{fix_case_up(name)}.new(*arg)
98
+ return @driver.#{name}(obj)
99
+ rescue SOAP::FaultError => fault
100
+ raise(Error::ApiError.new(fault),
101
+ "#{name} Call Failed: " + fault.faultstring.to_s, caller)
102
+ end
103
+ end
104
+ EOS
105
+ class_def += method_def
106
+ end
107
+
108
+ # Add extension methods, if any
109
+ extensions = AdWords::Extensions::extensions[[version, service]]
110
+ unless extensions.nil?
111
+ extensions.each do |ext|
112
+ params = AdWords::Extensions::methods[ext].join(', ')
113
+ arglist = 'self'
114
+ arglist += ", #{params}" if params != ''
115
+ method_def = <<-EOS
116
+ def #{ext}(#{params})
117
+ return AdWords::Extensions.#{ext}(#{arglist})
118
+ end
119
+ EOS
120
+ class_def += method_def
121
+ end
122
+ end
123
+
124
+ class_def += "end"
125
+ mod.class_eval(class_def)
126
+ end
127
+ return nil
128
+ end
129
+
130
+ # Returns the full module name for a given service
131
+ def self.get_module_name(version, service)
132
+ return "AdWords::V#{version.to_s}::#{service}Service"
133
+ end
134
+
135
+ # Returns the full interface class name for a given service
136
+ def self.get_interface_name(version, service)
137
+ if (version <= 13)
138
+ return get_module_name(version, service) + "::#{service}Interface"
139
+ else
140
+ return get_module_name(version, service) +
141
+ "::#{service}ServiceInterface"
142
+ end
143
+ end
144
+
145
+ # Returns the full wrapper class name for a given service
146
+ def self.get_wrapper_name(version, service)
147
+ return get_module_name(version, service) + "::#{service}ServiceWrapper"
148
+ end
149
+
150
+ private
151
+
152
+ def self.fix_case_up(name)
153
+ return name[0, 1].upcase + name[1..-1]
29
154
  end
30
155
  end
31
156
  end