google-adwords-api 0.2.0 → 0.2.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.
@@ -40,7 +40,7 @@ module AdwordsApi
40
40
  # Set other constants
41
41
  API_NAME = 'AdwordsApi'
42
42
  API_PATH = 'adwords_api'
43
- CLIENT_LIB_VERSION = '0.2.0'
43
+ CLIENT_LIB_VERSION = '0.2.1'
44
44
  DEFAULT_CONFIG_FILENAME = 'adwords_api.yml'
45
45
 
46
46
  # Configure the services available to each version
@@ -85,6 +85,7 @@ module AdwordsApi
85
85
  # Configure the different environments, with the base URL for each one
86
86
  @@environment_config = {
87
87
  :PRODUCTION => {
88
+ :oauth_scope => 'https://adwords.google.com/api/adwords/',
88
89
  :v13 => 'https://adwords.google.com/api/adwords/',
89
90
  :v200909 => 'https://adwords.google.com/api/adwords/',
90
91
  :v201003 => 'https://adwords.google.com/api/adwords/',
@@ -92,6 +93,7 @@ module AdwordsApi
92
93
  :v201101 => 'https://adwords.google.com/api/adwords/'
93
94
  },
94
95
  :SANDBOX => {
96
+ :oauth_scope => 'https://adwords-sandbox.google.com/api/adwords/',
95
97
  :v13 => 'https://sandbox.google.com/api/adwords/',
96
98
  :v200909 => 'https://adwords-sandbox.google.com/api/adwords/',
97
99
  :v201003 => 'https://adwords-sandbox.google.com/api/adwords/',
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
  #
3
3
  # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ # api.dklimkin@gmail.com (Danial Klimkin)
4
5
  #
5
6
  # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
6
7
  #
@@ -24,8 +25,6 @@ require 'adwords_api/api_config'
24
25
 
25
26
  module AdwordsApi
26
27
  class CredentialHandler < AdsCommon::CredentialHandler
27
- SERVICE_NAME = 'adwords'
28
-
29
28
  # Whether we're making MCC-level requests.
30
29
  attr_accessor :use_mcc
31
30
  # Whether we're making validate-only requests.
@@ -34,7 +33,7 @@ module AdwordsApi
34
33
  attr_accessor :partial_failure
35
34
 
36
35
  def initialize(config)
37
- super
36
+ super(config)
38
37
  @use_mcc = false
39
38
  @validate_only = false
40
39
  @partial_failure = false
@@ -44,18 +43,25 @@ module AdwordsApi
44
43
  # generation.
45
44
  def credentials(version = nil)
46
45
  validate_headers_for_server
47
- result = {}
46
+ method = @credentials[:method].to_s.upcase.to_sym
47
+ result = case method
48
+ when :CLIENTLOGIN
49
+ {:email => @credentials[:email],
50
+ :password => @credentials[:password]}
51
+ when :OAUTH
52
+ {:oauth_consumer_key => @credentials[:oauth_consumer_key],
53
+ :oauth_consumer_secret => @credentials[:oauth_consumer_secret],
54
+ :oauth_verification_code => @credentials[:oauth_verification_code],
55
+ :oauth_token => @credentials[:oauth_token],
56
+ :oauth_token_secret => @credentials[:oauth_token_secret],
57
+ :oauth_callback => @credentials[:oauth_callback],
58
+ :oauth_method => @credentials[:oauth_method]}
59
+ end
48
60
  client_lib = 'Ruby-AwApi-%s|' % AdwordsApi::ApiConfig::CLIENT_LIB_VERSION
49
- user_agent = @credentials[:user_agent]
50
- user_agent = $0 if user_agent.nil?
61
+ user_agent = @credentials[:user_agent] || $0
51
62
  user_agent = client_lib + user_agent
52
- if (version == :v13)
53
- result[:useragent] = user_agent
54
- else
55
- result[:userAgent] = user_agent
56
- end
57
- result[:email] = @credentials[:email]
58
- result[:password] = @credentials[:password]
63
+ user_agent_symbol = (version == :v13) ? :useragent : :userAgent
64
+ result[user_agent_symbol] = user_agent
59
65
  result[:developerToken] = @credentials[:developer_token]
60
66
  unless @use_mcc
61
67
  if @credentials[:client_email]
@@ -64,13 +70,11 @@ module AdwordsApi
64
70
  result[:clientCustomerId] = @credentials[:client_customer_id]
65
71
  end
66
72
  end
67
- if version != :v13 and @validate_only
68
- result[:validateOnly] = 'true'
69
- end
70
- if version != :v13 and @partial_failure
71
- result[:partialFailure] = 'true'
73
+ if version != :v13
74
+ result[:validateOnly] = 'true' if @validate_only
75
+ result[:partialFailure] = 'true' if @partial_failure
72
76
  end
73
- return result
77
+ return result.reject {|k,v| v.nil?}
74
78
  end
75
79
 
76
80
  private
@@ -83,28 +87,39 @@ module AdwordsApi
83
87
  # being used for production or vice-versa.
84
88
  #
85
89
  def validate_headers_for_server
86
- email = @credentials[:email]
90
+ method = @credentials[:method].to_s.upcase.to_sym
87
91
  token = @credentials[:developer_token]
88
- client = @credentials[:client_email]
89
- environment = @config.read('service.environment').to_s.upcase
90
-
91
- sandbox_token = (token =~ /#{Regexp.escape(email)}\+\+[a-zA-Z]{3}/)
92
- sandbox_client = (client =~ /client_[1-5]\+#{Regexp.escape(email)}/)
93
-
94
- # Only check the token, because 'client_n+x@y.tld' may be a valid client
95
- # email for some customers.
96
- if environment == 'PRODUCTION' and sandbox_token
97
- raise AdsCommon::Errors::EnvironmentMismatchError,
98
- 'Attempting to connect to production with sandbox credentials.'
99
- # Check if either the token or client email do not follow the correct
100
- # format. Client email may not exist, though.
101
- elsif environment == 'SANDBOX' and (!sandbox_token or
102
- (client.length > 0 and !sandbox_client))
103
- raise AdsCommon::Errors::EnvironmentMismatchError,
104
- 'Attempting to connect to the sandbox with malformatted ' +
105
- 'credentials. Please check ' +
106
- 'http://code.google.com/apis/adwords/docs/developer/' +
107
- 'adwords_api_sandbox.html#requestheaders for details.'
92
+ client_email = @credentials[:client_email]
93
+ (sandbox_token, sandbox_client) = case method
94
+ when :CLIENTLOGIN
95
+ email = @credentials[:email]
96
+ [(token =~ /#{Regexp.escape(email)}\+\+[a-zA-Z]{3}/),
97
+ (client_email =~ /client_[1-5]\+#{Regexp.escape(email)}/)]
98
+ when :OAUTH
99
+ [(token =~ /.+@.+\+\+[a-zA-Z]{3}/),
100
+ (client_email =~ /client_[1-5]\+.+@.+/)]
101
+ else
102
+ [nil, nil]
103
+ end
104
+ environment = @config.read('service.environment')
105
+ case environment
106
+ when :PRODUCTION
107
+ # Only check the token, because 'client_n+x@y.tld' may be a valid
108
+ # client email for some customers.
109
+ if sandbox_token
110
+ raise AdsCommon::Errors::EnvironmentMismatchError,
111
+ 'Attempting to connect to production with sandbox credentials.'
112
+ end
113
+ when :SANDBOX
114
+ # Check if either the token or client email do not follow the
115
+ # correct format. Client email may not exist, though.
116
+ if (!sandbox_token or (!client_email.empty? and !sandbox_client))
117
+ raise AdsCommon::Errors::EnvironmentMismatchError,
118
+ 'Attempting to connect to the sandbox with malformatted ' +
119
+ 'credentials. Please check ' +
120
+ 'http://code.google.com/apis/adwords/docs/developer/' +
121
+ 'adwords_api_sandbox.html#requestheaders for details.'
122
+ end
108
123
  end
109
124
  end
110
125
  end
@@ -354,7 +354,7 @@ module AdwordsApi
354
354
 
355
355
  # Makes sure object is an array.
356
356
  def self.arrayize(object)
357
- return Array.new if object.nil?
357
+ return [] if object.nil?
358
358
  return object.is_a?(Array) ? object : [object]
359
359
  end
360
360
 
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ #
5
+ # Copyright:: Copyright 2011, 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 AdwordsApi
25
+ class NestedHeaderHandler < SOAP::Header::SimpleHandler
26
+
27
+ def initialize(credential_handler, auth_handler, top_element_name,
28
+ top_namespace, inner_namespace, version = nil)
29
+ super(XSD::QName.new(top_namespace, top_element_name))
30
+ @credential_handler = credential_handler
31
+ @auth_handler = auth_handler
32
+ @ns = inner_namespace
33
+ @version = version
34
+ end
35
+
36
+ # Handles callback.
37
+ def on_simple_outbound
38
+ main_header = SOAP::SOAPElement.new(nil)
39
+ credentials = @credential_handler.credentials
40
+ @auth_handler.headers(credentials).each do |cred, value|
41
+ cred_header = SOAP::SOAPElement.new(XSD::QName.new(@ns, cred), value)
42
+ main_header.add(cred_header)
43
+ end
44
+ return main_header
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ #
5
+ # Copyright:: Copyright 2011, 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 AdwordsApi
25
+ class SingleHeaderHandler < SOAP::Header::SimpleHandler
26
+
27
+ def initialize(credential_handler, auth_handler,
28
+ element_name, element_namespace = nil, version = nil)
29
+ super(XSD::QName.new(element_namespace, element_name))
30
+ @credential_handler = credential_handler
31
+ @auth_handler = auth_handler
32
+ @element_name = element_name
33
+ @version = version
34
+ end
35
+
36
+ def on_simple_outbound
37
+ credentials = @credential_handler.credentials
38
+ return @auth_handler.headers(credentials)[@element_name]
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,345 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ # api.jeffy@gmail.com (Jeffrey Posnick)
5
+ # chanezon@google.com (Patrick Chanezon)
6
+ # leavengood@gmail.com (Ryan Leavengood)
7
+ #
8
+ # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
9
+ #
10
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
11
+ # you may not use this file except in compliance with the License.
12
+ # You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS,
18
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
19
+ # implied.
20
+ # See the License for the specific language governing permissions and
21
+ # limitations under the License.
22
+ #
23
+ # Common Rake tasks for Soap4r-based AdWords client library.
24
+
25
+ require 'rubygems'
26
+ gem 'rake'
27
+ gem 'soap4r', '=1.5.8'
28
+ require 'fileutils'
29
+ require 'logger'
30
+ require 'rake/gempackagetask'
31
+ require 'rake/rdoctask'
32
+ require 'rake/clean'
33
+ require 'rake/testtask'
34
+ require 'wsdl/soap/wsdl2ruby'
35
+ require 'xsd/codegen/classdef'
36
+
37
+ require 'ads_common/http'
38
+
39
+ require 'adwords_api/soap4r/soap4r_patches'
40
+
41
+ $API_CONFIG = $MODULE::ApiConfig
42
+
43
+ $WSDLDIR = 'wsdl'
44
+ $LIBDIR = 'lib'
45
+ $DOCDIR = 'doc'
46
+ $TESTDIR = 'test'
47
+ $GENDIR = File.join($LIBDIR, $PROJECT_NAME)
48
+ $PKG_VERSION = ENV['REL'] ? ENV['REL'] : $CURRENT_VERSION
49
+
50
+ SRC_RB = FileList["#{$LIBDIR}/**/*.rb"]
51
+
52
+ logger = Logger.new(STDOUT)
53
+ logger.level = Logger::INFO
54
+
55
+ CLEAN.include($WSDLDIR)
56
+ CLEAN.include($DOCDIR)
57
+ $API_CONFIG.versions.each do |version|
58
+ CLEAN.include(File.join($GENDIR, version.to_s))
59
+ end
60
+
61
+ CLOBBER.include('pkg')
62
+
63
+ # ====================================================================
64
+ # Create a default task to prepare library for usage.
65
+ desc "gets the wsdl and generates the classes"
66
+ task :default => [:getwsdl, :generate]
67
+
68
+ # ====================================================================
69
+ # Create a task to retrieve the WSDL files for the services.
70
+ desc "gets the wsdl files for API services"
71
+ task :getwsdl do
72
+ $API_CONFIG.versions.each do |version|
73
+ urls = $API_CONFIG.get_wsdls(version)
74
+ mkdir_p File.join($WSDLDIR, version.to_s)
75
+ config = Generator.config
76
+ config.set('library.logger', logger)
77
+ urls.each do |service, url|
78
+ logger.info("Getting #{url}...")
79
+ save(AdsCommon::Http.get(url, config),
80
+ get_wsdl_file_name(version.to_s, service.to_s))
81
+ end
82
+ end
83
+ end
84
+
85
+ # Return the full file name of the WSDL file for a given version and service
86
+ def get_wsdl_file_name(version, service)
87
+ File.join($WSDLDIR, version.to_s, service.to_s) + '.wsdl'
88
+ end
89
+
90
+ # Apply fixes to the WSDL content in order to make it understandable for the
91
+ # soap4r code generator. The fixes are applied to the original object.
92
+ def fix_wsdl!(wsdl)
93
+ ['type', 'base'].each do |name|
94
+ ['long', 'string', 'date', 'int', 'boolean'].each do |type|
95
+ # Fix this attribute over the entire document
96
+ wsdl.gsub!(Regexp.new("#{name}=\"#{type}\""), "#{name}=\"xsd:#{type}\"")
97
+ end
98
+ end
99
+ schema_ns = "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
100
+ if wsdl !~ Regexp.new(schema_ns)
101
+ wsdl.gsub!(/(<wsdl:definitions[^>]*)>/, '\1 ' + schema_ns + '>')
102
+ end
103
+ return wsdl
104
+ end
105
+
106
+ # Saves this document to the specified path.
107
+ # Doesn't create the file if a 404 error page is returned.
108
+ def save(content, path)
109
+ if content !~ /<H2>Error 404<\/H2>/
110
+ File::open(path, 'w') {|f| f.write(fix_wsdl!(content))}
111
+ end
112
+ end
113
+
114
+ # ====================================================================
115
+ # Set the default generation task to use soap4r (can be overriden for client
116
+ # libraries).
117
+ desc "generates API classes from the wsdl files"
118
+ task :generate => [:soap4r_generate]
119
+
120
+ # ====================================================================
121
+ # Create a task to generate all the service classes with soap4r.
122
+ desc "generates API classes from the wsdl files using soap4r"
123
+ task :soap4r_generate do
124
+ $API_CONFIG.versions.each do |version|
125
+ gendir = File.join($LIBDIR, $PRODDIR, version.to_s)
126
+ mkdir_p gendir
127
+ $API_CONFIG.services(version).each do |service|
128
+ # Generate SOAP classes with soap4r
129
+ service_name = service.to_s
130
+ worker = WSDL::SOAP::WSDL2Ruby.new
131
+ worker.logger = logger
132
+ worker.location = get_wsdl_file_name(version, service)
133
+ worker.basedir = gendir
134
+ worker.opt.update(get_wsdl_opt(version, service_name))
135
+ worker.run
136
+
137
+ # Fix the "require" statements so that they work in the client library's
138
+ # directory structure
139
+ fix_import(version, File.join(gendir, "#{service_name}Driver.rb"))
140
+ fix_import(version,
141
+ File.join(gendir, "#{service_name}MappingRegistry.rb"))
142
+ fix_import(version, File.join(gendir, "#{service_name}.rb"))
143
+
144
+ # Fix the comments in the file so that we get better-looking RDoc, and
145
+ # only for the things we want
146
+ fix_rdoc(File.join(gendir, "#{service_name}.rb"))
147
+
148
+ # Generate the wrapper files
149
+ eval("require '#{File.join(gendir, "#{service_name}Driver.rb")}'")
150
+ wrapper_file = File.join(gendir, "#{service_name}Wrapper.rb")
151
+ File.open(wrapper_file, 'w') do |file|
152
+ file.write(Generator.generate_wrapper_class(version, service))
153
+ end
154
+ logger.info("Generated #{version} #{service_name} " +
155
+ "wrapper: #{wrapper_file}")
156
+ end
157
+ end
158
+ end
159
+
160
+ # Fix "require" statements for client lib usage
161
+ def fix_import(version, file)
162
+ tempfile = file + '.tmp'
163
+ outfile = File.new(tempfile, 'w')
164
+ File.open(file, 'r') do |infile|
165
+ infile.each do |line|
166
+ if (line =~ /require.*Service.*\.rb/)
167
+ outfile << line.gsub(/require '(.*)Service(.*)\.rb'/,
168
+ "require '#{$PRODDIR}/#{version.to_s}/\\1Service\\2'")
169
+ else
170
+ outfile << line
171
+ end
172
+ end
173
+ end
174
+ outfile.close
175
+ File.rename(tempfile, file)
176
+ end
177
+
178
+ # Fix RDoc comments in the generated *Service.rb files
179
+ def fix_rdoc(file)
180
+ tempfile = file + '.tmp'
181
+ outfile = File.new(tempfile, 'w')
182
+ should_doc = true
183
+ File.open(file, 'r') do |infile|
184
+ infile.each do |line|
185
+ if (line =~ /# \{.*\}[A-Z]\w*/)
186
+ # This is a regular class. Document and clean up how it's displayed.
187
+ should_doc = true
188
+ outfile << line.gsub(/\{.*\}(.*)/, "\\1")
189
+ elsif (line =~ /# \{.*\}[a-z]\w*/)
190
+ # This is a method wrapping class. Do not document, but still clean up
191
+ # its comment.
192
+ should_doc = false
193
+ outfile << line.gsub(/\{.*\}(.*)/, "\\1")
194
+ elsif (line =~ /# \w+/)
195
+ # Itemize member variables
196
+ outfile << line.gsub(/# (.*)/, "# - \\1")
197
+ elsif (line =~ /class [A-Z].*/)
198
+ if should_doc
199
+ outfile << line
200
+ else
201
+ # Avoid documenting the method classes, since they're made invisible
202
+ # thanks to our service wrappers
203
+ outfile << line.gsub(/(.*)(\w)/, "\\1\\2 #:nodoc: all")
204
+ end
205
+ else
206
+ outfile << line
207
+ end
208
+ end
209
+ end
210
+ outfile.close
211
+ File.rename(tempfile, file)
212
+ end
213
+
214
+ # Create options to be used for class generation from WSDL
215
+ def get_wsdl_opt(version, service_name)
216
+ optcmd= {}
217
+ optcmd['classdef'] = service_name
218
+ optcmd['force'] = true
219
+ optcmd['mapping_registry'] = true
220
+ optcmd['driver'] = nil
221
+
222
+ # Causes soap4r to wrap the classes it outputs into the given modules
223
+ optcmd['module_path'] = [$MODULE.name, version.to_s.capitalize, service_name]
224
+ return optcmd
225
+ end
226
+
227
+ # ====================================================================
228
+ # Create a task to build the RDOC documentation tree.
229
+ Rake::RDocTask.new("rdoc") do |rdoc|
230
+ # Try to use SDoc to generate the docs
231
+ begin
232
+ require 'sdoc'
233
+ rdoc.options << '--fmt' << 'shtml'
234
+ rdoc.template = 'direct'
235
+ rescue LoadError
236
+ # Do nothing, give up on SDoc and continue with whatever is the default.
237
+ end
238
+ rdoc.rdoc_dir = $DOCDIR
239
+ rdoc.title = "#{$PROJECT_NAME} -- Client library for the #{$API_NAME}"
240
+ rdoc.main = 'README'
241
+ rdoc.rdoc_files.include('README', 'COPYING', 'ChangeLog')
242
+ rdoc.rdoc_files.include("#{$LIBDIR}/*.rb", "#{$LIBDIR}/#{$PRODDIR}/*.rb")
243
+ rdoc.rdoc_files.include("#{$LIBDIR}/#{$PRODDIR}/v*/*Wrapper.rb")
244
+ rdoc.rdoc_files.include("#{$LIBDIR}/#{$PRODDIR}/v*/*Service.rb")
245
+ rdoc.rdoc_files.exclude("#{$LIBDIR}/#{$PRODDIR}/soap4rpatches.rb")
246
+ end
247
+
248
+ # ====================================================================
249
+ # Create a task to perform the unit testing.
250
+ Rake::TestTask.new("test") do |test|
251
+ test.libs << $TESTDIR
252
+ test.pattern = "#{$TESTDIR}/**/test_*.rb"
253
+ test.verbose = true
254
+ end
255
+
256
+ # ====================================================================
257
+ # Create a task that will package the Rake software into distributable
258
+ # gem files.
259
+
260
+ # Utility method to create readable version ranges. May not cover a few edge
261
+ # cases, but this is a best effort approach.
262
+ def readable_version_range(version_string)
263
+ return '' if version_string.nil?
264
+
265
+ version_string = version_string.to_s.strip
266
+ pattern = /^(>|<|>=|<=|~>)(\s*)(\d[\d\.]*)$/
267
+ result = pattern.match(version_string)
268
+
269
+ return version_string unless result
270
+
271
+ case result[1]
272
+ when '>'
273
+ return 'greater than version ' + result[3]
274
+ when '<'
275
+ return 'lower than version ' + result[3]
276
+ when '>='
277
+ return 'version ' + result[3] + ' or later'
278
+ when '<='
279
+ return 'version ' + result[3] + ' or earlier'
280
+ when '~>'
281
+ version_pattern = /^(\d[\d\.]*)(\d)$/
282
+ version_result = version_pattern.match(result[3])
283
+ if version_result
284
+ return 'version ' + version_result[1] + 'x'
285
+ else
286
+ return version_string
287
+ end
288
+ else
289
+ return version_string
290
+ end
291
+ end
292
+
293
+ PKG_FILES = FileList[
294
+ '*.*',
295
+ 'Rakefile',
296
+ "#{$LIBDIR}/**/*.rb",
297
+ "#{$LIBDIR}/#{$PRODDIR}/data/*.*",
298
+ 'examples/**/*.rb',
299
+ "#{$DOCDIR}/**/*.*",
300
+ "#{$TESTDIR}/**/*.*"
301
+ ]
302
+
303
+ PKG_FILES.exclude(/\._/)
304
+
305
+ if ! defined?(Gem)
306
+ logger.fatal('Package Target requires RubyGems')
307
+ else
308
+ spec = Gem::Specification.new do |s|
309
+
310
+ # Basic information
311
+ s.name = $GEM_NAME
312
+ s.version = $PKG_VERSION
313
+ s.summary = $GEM_SUMMARY
314
+ s.description = $GEM_DESCRIPTION
315
+
316
+ # Files and dependencies
317
+ dependencies = [['soap4r', '= 1.5.8'],
318
+ ['httpclient', '>= 2.1.2'],
319
+ ['google-ads-common', $ADS_COMMON_VERSION]]
320
+ dependencies += $EXTRA_DEPENDENCIES if $EXTRA_DEPENDENCIES
321
+ s.files = PKG_FILES.to_a
322
+ s.require_path = $LIBDIR
323
+ dependencies.each do |dep|
324
+ s.add_dependency(dep[0], dep[1])
325
+ end
326
+
327
+ # RDoc information
328
+ s.has_rdoc = true
329
+ s.extra_rdoc_files = ['README', 'COPYING', 'ChangeLog']
330
+ s.rdoc_options << '--main' << 'README'
331
+
332
+ # Metadata
333
+ s.authors = $GEM_AUTHORS
334
+ s.email = $GEM_EMAIL
335
+ s.homepage = $GEM_HOMEPAGE
336
+ s.rubyforge_project = $PROJECT_NAME
337
+ dependencies.each do |dep|
338
+ s.requirements << dep[0] + ' ' + readable_version_range(dep[1])
339
+ end
340
+ end
341
+
342
+ Rake::GemPackageTask.new(spec) do |t|
343
+ t.need_tar = true
344
+ end
345
+ end