sem4r 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. data/Gemfile +13 -2
  2. data/Gemfile.lock +13 -7
  3. data/README.rdoc +44 -7
  4. data/Rakefile +2 -122
  5. data/VERSION.yml +1 -1
  6. data/bin/sem +1 -0
  7. data/examples_sem4r/01_get_account.rb +1 -0
  8. data/examples_sem4r/02_get_info.rb +1 -0
  9. data/examples_sem4r/03_list_ad.rb +1 -0
  10. data/examples_sem4r/04_list_keywords.rb +1 -0
  11. data/examples_sem4r/05_request_report.rb +25 -14
  12. data/examples_sem4r/{05_request_report_2010.rb → 06_request_report_definition.rb} +2 -4
  13. data/examples_sem4r/{06_create_campaigns.rb → 07_create_campaigns.rb} +1 -0
  14. data/examples_sem4r/{07_create_campaigns_block.rb → 08_create_campaigns_block.rb} +1 -0
  15. data/examples_sem4r/{07_create_campaigns_simple.rb → 09_create_campaigns_simple.rb} +1 -0
  16. data/examples_sem4r/{08_ad_params.rb → 10_ad_params.rb} +1 -0
  17. data/examples_sem4r/{09_targeting_idea.rb → 11_targeting_idea.rb} +1 -0
  18. data/examples_sem4r/{10_get_location.rb → 12_get_location.rb} +1 -0
  19. data/examples_sem4r/{11_submit_bulk_job.rb → 13_submit_bulk_job.rb} +1 -1
  20. data/examples_sem4r/{12_list_bulk_job.rb → 14_list_bulk_job.rb} +3 -0
  21. data/examples_sem4r/30_prune_empty_adgroup.rb +1 -0
  22. data/examples_sem4r/31_empty_accounts.rb +1 -0
  23. data/examples_sem4r/example_helper.rb +2 -1
  24. data/lib/sem4r/ad_group/ad_group.rb +22 -7
  25. data/lib/sem4r/ad_group/ad_group_bids.rb +1 -1
  26. data/lib/sem4r/ad_group/ad_group_service.rb +12 -5
  27. data/lib/sem4r/ad_group_ad/ad_group_ad.rb +1 -0
  28. data/lib/sem4r/ad_group_ad/ad_group_ad_operations.rb +1 -0
  29. data/lib/sem4r/ad_group_ad/ad_group_ad_service.rb +14 -9
  30. data/lib/sem4r/ad_group_ad/ad_group_mobile_ad.rb +16 -25
  31. data/lib/sem4r/ad_group_ad/ad_group_text_ad.rb +18 -14
  32. data/lib/sem4r/ad_group_criterion/ad_group_criterion.rb +27 -19
  33. data/lib/sem4r/ad_group_criterion/ad_group_criterion_bids.rb +2 -1
  34. data/lib/sem4r/ad_group_criterion/ad_group_criterion_operations.rb +1 -0
  35. data/lib/sem4r/ad_group_criterion/ad_group_criterion_service.rb +9 -4
  36. data/lib/sem4r/ad_group_criterion/criterion.rb +1 -0
  37. data/lib/sem4r/ad_group_criterion/criterion_keyword.rb +1 -0
  38. data/lib/sem4r/ad_group_criterion/criterion_placement.rb +1 -0
  39. data/lib/sem4r/ad_param/ad_param.rb +24 -8
  40. data/lib/sem4r/ad_param/ad_param_service.rb +8 -5
  41. data/lib/sem4r/adwords.rb +232 -76
  42. data/lib/sem4r/base.rb +1 -1
  43. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job.rb +41 -35
  44. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_account_extension.rb +49 -15
  45. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_selector.rb +29 -20
  46. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_service.rb +13 -14
  47. data/lib/sem4r/bulk_mutate_job/job_operations.rb +1 -1
  48. data/lib/sem4r/campaign/campaign.rb +1 -0
  49. data/lib/sem4r/campaign/campaign_account_extension.rb +2 -1
  50. data/lib/sem4r/campaign/campaign_service.rb +9 -5
  51. data/lib/sem4r/credentials.rb +11 -5
  52. data/lib/sem4r/geo_location/address.rb +56 -0
  53. data/lib/sem4r/geo_location/geo_location_account_extension.rb +27 -6
  54. data/lib/sem4r/geo_location/geo_location_selector.rb +57 -0
  55. data/lib/sem4r/geo_location/geo_location_service.rb +9 -16
  56. data/lib/sem4r/info/info_account_extension.rb +3 -2
  57. data/lib/sem4r/info/info_selector.rb +2 -1
  58. data/lib/sem4r/info/info_service.rb +10 -3
  59. data/lib/sem4r/operation.rb +39 -20
  60. data/lib/sem4r/report_definition/report_definition.rb +37 -19
  61. data/lib/sem4r/report_definition/report_definition_account_extension.rb +66 -16
  62. data/lib/sem4r/report_definition/report_definition_operation.rb +2 -2
  63. data/lib/sem4r/report_definition/report_definition_selector.rb +1 -1
  64. data/lib/sem4r/report_definition/report_definition_service.rb +11 -7
  65. data/lib/sem4r/report_definition/report_field.rb +3 -2
  66. data/lib/sem4r/sem4r_templates.rb +77 -0
  67. data/lib/sem4r/{services/service.rb → service.rb} +23 -23
  68. data/lib/sem4r/targeting_idea/targeting_idea.rb +4 -4
  69. data/lib/sem4r/targeting_idea/targeting_idea_account_extension.rb +1 -1
  70. data/lib/sem4r/targeting_idea/targeting_idea_selector.rb +6 -6
  71. data/lib/sem4r/targeting_idea/targeting_idea_service.rb +7 -5
  72. data/lib/sem4r/v13_account/account_account_extension.rb +7 -10
  73. data/lib/sem4r/v13_account/account_service.rb +10 -4
  74. data/lib/sem4r/v13_account/billing_address.rb +2 -2
  75. data/lib/sem4r/v13_report/report_service.rb +11 -9
  76. data/lib/sem4r.rb +46 -31
  77. data/lib/{sem4r/cli → sem4r_cli}/cli_helpers.rb +3 -2
  78. data/lib/{sem4r/cli/cli_command.rb → sem4r_cli/cli_mini_framework.rb} +77 -32
  79. data/lib/{sem4r/cli/cli_common_args.rb → sem4r_cli/cli_sem.rb} +177 -157
  80. data/lib/{sem4r/cli/commands/cli_list_ads.rb → sem4r_cli/commands/cli_ads.rb} +7 -9
  81. data/lib/sem4r_cli/commands/cli_campaign.rb +69 -0
  82. data/lib/{sem4r/cli/commands/cli_list_client.rb → sem4r_cli/commands/cli_clients.rb} +2 -2
  83. data/lib/{sem4r/cli → sem4r_cli}/commands/cli_ideas.rb +35 -27
  84. data/lib/{sem4r/cli → sem4r_cli}/commands/cli_info.rb +3 -4
  85. data/lib/{sem4r/cli/commands/cli_repdef.rb → sem4r_cli/commands/cli_job.rb} +57 -55
  86. data/lib/{sem4r/cli/commands/cli_list_keywords.rb → sem4r_cli/commands/cli_keywords.rb} +14 -13
  87. data/lib/sem4r_cli/commands/cli_profile.rb +138 -0
  88. data/lib/{sem4r/cli/commands/cli_report.rb → sem4r_cli/commands/cli_repdef.rb} +67 -20
  89. data/lib/{sem4r/cli/commands/cli_request_report.rb → sem4r_cli/commands/cli_report.rb} +82 -19
  90. data/lib/sem4r_cli.rb +5 -7
  91. data/lib/sem4r_soap/http_connector.rb +206 -0
  92. data/lib/{soap_helpers → sem4r_soap}/soap_attributes.rb +8 -3
  93. data/lib/{sem4r/services → sem4r_soap}/soap_dumper.rb +36 -20
  94. data/lib/{sem4r/services → sem4r_soap}/soap_error.rb +5 -2
  95. data/lib/sem4r_soap/soap_response.rb +75 -0
  96. data/lib/sem4r_soap/soap_service.rb +137 -0
  97. data/lib/{sem4r/cli/cli_sem.rb → sem4r_soap/soap_service_v13.rb} +27 -28
  98. data/lib/sem4r_soap/soap_service_v2010.rb +80 -0
  99. data/lib/sem4r_soap.rb +17 -0
  100. data/sem4r.gemspec +93 -58
  101. data/spec/build_fixtures.rb +49 -42
  102. data/spec/fixtures/password.example.yml +3 -0
  103. data/spec/fixtures/sem4r.example.yml +6 -0
  104. data/spec/fixtures/{services/error.xml → soap_error.xml} +0 -0
  105. data/spec/fixtures/soap_error2.xml +29 -0
  106. data/spec/helpers/dump_interceptor.rb +90 -0
  107. data/spec/helpers/fixtures_bulk_mutate_job.rb +48 -0
  108. data/spec/helpers/fixtures_geo_location.rb +45 -0
  109. data/{lib/sem4r/campaign_criterion/campaign_criterion_service.rb → spec/helpers/fixtures_info.rb} +10 -6
  110. data/spec/helpers/fixtures_report_definition.rb +65 -0
  111. data/spec/{rspec_hash.rb → helpers/rspec_hash.rb} +1 -0
  112. data/spec/{rspec_matchers.rb → helpers/rspec_matchers.rb} +46 -19
  113. data/spec/{rspec_sem4r_helper.rb → helpers/rspec_sem4r_helper.rb} +19 -16
  114. data/spec/{sem4r_stubs.rb → helpers/sem4r_stubs.rb} +5 -4
  115. data/spec/rspec_helper.rb +4 -4
  116. data/spec/sem4r/account_spec.rb +2 -3
  117. data/spec/sem4r/ad_group/ad_group_service_spec.rb +1 -1
  118. data/spec/sem4r/ad_group/ad_group_spec.rb +1 -1
  119. data/spec/sem4r/ad_group_ad/ad_group_ad_operation_spec.rb +3 -3
  120. data/spec/sem4r/adwords_spec.rb +62 -39
  121. data/{lib/sem4r/cli/commands/cli_list_campaign.rb → spec/sem4r/bulk_mutate_job/bulk_mutate_job_selector_spec.rb} +14 -11
  122. data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_service_spec.rb +2 -3
  123. data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_spec.rb +23 -17
  124. data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-req.xml +35 -0
  125. data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-res.xml +417 -0
  126. data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-req.xml +106 -0
  127. data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-res.xml +48 -0
  128. data/spec/sem4r/bulk_mutate_job/job_operation_spec.rb +5 -7
  129. data/spec/sem4r/campaign/campaign_service_spec.rb +2 -2
  130. data/spec/sem4r/credentials_spec.rb +10 -8
  131. data/spec/sem4r/geo_location/address_spec.rb +62 -0
  132. data/spec/sem4r/geo_location/fixtures/get-req.xml +42 -0
  133. data/spec/sem4r/geo_location/fixtures/get-res.xml +60 -0
  134. data/spec/sem4r/info/fixtures/get-req.xml +34 -0
  135. data/spec/sem4r/info/fixtures/get-res.xml +27 -0
  136. data/spec/sem4r/nokogiri_parsing_spec.rb +1 -0
  137. data/spec/sem4r/operation_spec.rb +72 -0
  138. data/spec/sem4r/report_definition/fixtures/get-list-repdef-req.xml +22 -0
  139. data/spec/sem4r/report_definition/fixtures/get-list-repdef-res.xml +73 -0
  140. data/spec/sem4r/report_definition/fixtures/getReportFields-req.xml +24 -0
  141. data/spec/sem4r/report_definition/fixtures/getReportFields-res.xml +1199 -0
  142. data/spec/sem4r/report_definition/fixtures/mutate-add-report-req.xml +63 -0
  143. data/spec/sem4r/report_definition/fixtures/mutate-add-report-res.xml +68 -0
  144. data/spec/sem4r/report_definition/report_definition_service_spec.rb +5 -5
  145. data/spec/sem4r/report_definition/report_definition_spec.rb +28 -43
  146. data/{lib/sem4r/cli/commands/cli_list_report.rb → spec/sem4r/report_definition/report_field_spec.rb} +12 -10
  147. data/spec/sem4r/rexml_parsing_spec.rb +1 -0
  148. data/spec/sem4r/{services/service_spec.rb → service_spec.rb} +1 -1
  149. data/spec/sem4r/targeting_idea/targeting_idea_selector_spec.rb +1 -1
  150. data/spec/sem4r/targeting_idea/targeting_idea_service_spec.rb +1 -1
  151. data/spec/sem4r/targeting_idea/targeting_idea_spec.rb +1 -1
  152. data/spec/sem4r/v13_account/account_service_spec.rb +2 -2
  153. data/spec/sem4r/v13_report/report_service_spec.rb +2 -2
  154. data/spec/{sem4r/cli → sem4r_cli}/cli_spec.rb +22 -27
  155. data/spec/{soap_helpers → sem4r_soap}/soap_attributes_spec.rb +3 -3
  156. data/spec/{sem4r/services/soap_message_v13_spec.rb → sem4r_soap/soap_response_spec.rb} +10 -15
  157. data/spec/{sem4r/services/soap_call_spec.rb → sem4r_soap/soap_service_spec.rb} +35 -54
  158. data/tasks/jeweler.rake +66 -0
  159. data/tasks/rspec.rake +21 -0
  160. data/tasks/sem4r.rake +25 -0
  161. data/tasks/yard.rake +31 -0
  162. metadata +173 -76
  163. data/lib/sem4r/ad_extension_override/ad_extension_override_service.rb +0 -30
  164. data/lib/sem4r/api_counters.rb +0 -8
  165. data/lib/sem4r/campaign_target/campaign_target_service.rb +0 -30
  166. data/lib/sem4r/cli/commands/cli_download_report.rb +0 -82
  167. data/lib/sem4r/services/http_connector.rb +0 -93
  168. data/lib/sem4r/services/soap_call.rb +0 -122
  169. data/lib/sem4r/services/soap_connector.rb +0 -139
  170. data/lib/sem4r/services/soap_message_v13.rb +0 -135
  171. data/lib/sem4r/services/soap_message_v2010.rb +0 -184
  172. data/lib/sem4r/v13_traffic_estimator/traffic_estimator_service.rb +0 -30
  173. data/spec/aggregates_rspec_helper.rb +0 -59
  174. data/spec/sem4r/report_definition/fixtures/mutate_add-req.xml +0 -24
  175. data/spec/sem4r/report_definition/fixtures/mutate_add-req_orig.xml +0 -45
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,12 +20,22 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  module Sem4r
26
26
  class BulkMutateJobSelector
27
- include SoapAttributes
27
+ include Sem4rSoap::SoapAttributes
28
+
29
+ enum :JobStatuses, [
30
+ :COMPLETED,
31
+ :PROCESSING,
32
+ :FAILED,
33
+ :PENDING]
34
+
35
+ g_set_accessor :status, {:values_in => :JobStatuses}
36
+ g_set_accessor :jobId
37
+ g_accessor :stats
38
+ g_accessor :history
28
39
 
29
40
  def initialize(&block)
30
41
  if block_given?
@@ -32,25 +43,23 @@ module Sem4r
32
43
  end
33
44
  end
34
45
 
35
- enum :JobStatuses, [
36
- :COMPLETED,
37
- :PROCESSING,
38
- :FAILED,
39
- :PENDING]
40
-
41
- def to_xml
42
- <<-EOFS
43
- <selector>
44
- <customerJobKeys></customerJobKeys>
45
- <jobStatuses>COMPLETED</jobStatuses>
46
- <jobStatuses>PROCESSING</jobStatuses>
47
- <jobStatuses>FAILED</jobStatuses>
48
- <jobStatuses>PENDING</jobStatuses>
49
- </selector>
50
- EOFS
51
- end
46
+ def to_xml(tag = "selector")
47
+ builder = Builder::XmlMarkup.new
48
+ builder.tag!(tag) do |t|
52
49
 
53
- ##########################################################################
50
+ t.includeHistory history unless history.nil?
51
+ t.includeStats stats unless stats.nil?
52
+
53
+ unless jobIds.empty?
54
+ jobIds.each { |i| t.jobIds i }
55
+ end
56
+
57
+
58
+ unless statuss.empty?
59
+ statuss.each { |f| t.jobStatuses f }
60
+ end
61
+ end
62
+ end
54
63
 
55
64
  end
56
65
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,38 +20,36 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  module Sem4r
26
- class BulkMutateJobService
27
- include SoapCall
26
+
27
+ #
28
+ # @private
29
+ #
30
+ class BulkMutateJobService < Sem4rSoap::SoapServiceV2010
28
31
 
29
32
  def initialize(connector)
30
33
  @connector = connector
31
-
32
34
  @service_namespace = "https://adwords.google.com/api/adwords/cm/v201008"
33
35
  @header_namespace = @service_namespace
34
36
 
35
37
  @sandbox_service_url = "https://adwords-sandbox.google.com/api/adwords/job/v201008/BulkMutateJobService"
36
38
  @production_service_url = "https://adwords.google.com/api/adwords/job/v201008/BulkMutateJobService"
39
+ init(@header_namespace, @service_namespace)
37
40
  end
38
41
 
39
- soap_call_v2010 :all, :mutate => false
40
- soap_call_v2010 :mutate
42
+ soap_call :get, :mutate => false
43
+ soap_call :mutate
41
44
 
42
45
  private
43
46
 
44
- def _all(selector)
45
- "<get xmlns=\"#{@service_namespace}\">" + selector.to_xml + '</get>';
47
+ def _get(xml)
48
+ "<get xmlns=\"#{@service_namespace}\">#{xml}</get>";
46
49
  end
47
50
 
48
- def _mutate(job_operation)
49
- <<-EOFS
50
- <mutate xmlns="#{@service_namespace}">
51
- #{job_operation.to_xml('operation')}
52
- </mutate>
53
- EOFS
51
+ def _mutate(xml)
52
+ "<mutate xmlns=\"#{@service_namespace}\">#{xml}</mutate>"
54
53
  end
55
54
 
56
55
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,7 +20,6 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  module Sem4r
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -70,7 +71,7 @@ module Sem4r
70
71
  private
71
72
 
72
73
  def _campaigns
73
- soap_message = service.campaign.all(credentials)
74
+ soap_message = service.campaign.all( credentials )
74
75
  add_counters( soap_message.counters )
75
76
  rval = soap_message.response.at_xpath("//getResponse/rval")
76
77
  els = rval.xpath("entries")
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -23,8 +24,10 @@
23
24
 
24
25
  module Sem4r
25
26
 
26
- class CampaignService
27
- include SoapCall
27
+ #
28
+ # @private
29
+ #
30
+ class CampaignService < Sem4rSoap::SoapServiceV2010
28
31
 
29
32
  def initialize(connector)
30
33
  @connector = connector
@@ -32,11 +35,12 @@ module Sem4r
32
35
  @header_namespace = @service_namespace
33
36
 
34
37
  @sandbox_service_url = "https://adwords-sandbox.google.com/api/adwords/cm/v201008/CampaignService"
38
+ init(@header_namespace, @service_namespace)
35
39
  end
36
40
 
37
- soap_call_v2010 :all, :mutate => false
38
- soap_call_v2010 :create
39
- soap_call_v2010 :delete
41
+ soap_call :all, :mutate => false
42
+ soap_call :create
43
+ soap_call :delete
40
44
 
41
45
  private
42
46
 
@@ -75,12 +75,18 @@ module Sem4r
75
75
 
76
76
  def authentication_token
77
77
  return @authentication_token if @authentication_token
78
- if @credentials
79
- return @authentication_token = @credentials.authentication_token
80
- end
78
+ return @authentication_token = @credentials.authentication_token if @credentials
81
79
  raise "no connector in credentials! use credentials.connector=" unless @connector
82
- @authentication_token = @connector.authentication_token(@email, @password)
83
- @authentication_token
80
+
81
+ url = "https://www.google.com/accounts/ClientLogin"
82
+ query = "accountType=GOOGLE&Email=#{URI.escape(email)}&Passwd=#{URI.escape(password)}&service=adwords"
83
+ headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
84
+ response = @connector.post(url, query, headers )
85
+ status = response.code.to_i
86
+ if status != 200
87
+ raise Sem4rError, "authentication failed status is #{status}"
88
+ end
89
+ @authentication_token = response.body[/Auth=(.*)/, 1]
84
90
  end
85
91
 
86
92
  end
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -------------------------------------------------------------------------
3
+ # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ # -------------------------------------------------------------------------
24
+
25
+ module Sem4r
26
+ class Address
27
+ include Sem4rSoap::SoapAttributes
28
+
29
+ g_accessor :address, :xpath => 'streetAddress'
30
+ g_accessor :address2, :xpath => 'streetAddress2'
31
+ g_accessor :city, :xpath => 'cityName'
32
+ g_accessor :province_code, :xpath => 'provinceCode'
33
+ g_accessor :province, :xpath => 'provinceName'
34
+ g_accessor :postal_code, :xpath => 'postalCode'
35
+ g_accessor :country, :xpath => 'countryCode'
36
+
37
+ def initialize(&block)
38
+ if block_given?
39
+ block.arity < 1 ? instance_eval(&block) : block.call(self)
40
+ end
41
+ end
42
+
43
+ def self.from_element(*args)
44
+ _from_element(*args)
45
+ end
46
+
47
+ def to_xml(tag = "addresses")
48
+ _to_xml(tag)
49
+ end
50
+
51
+ def to_s
52
+ _to_s
53
+ end
54
+
55
+ end
56
+ end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,18 +20,38 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  module Sem4r
26
26
 
27
27
  module GeoLocationAccountExtension
28
- ############################################################################
29
- # Geo Location
30
28
 
31
- def geo_location
32
- soap_message = service.geo_location.get(@credentials, "")
33
- add_counters( soap_message.counters )
29
+ # Call geolocation adwords service
30
+ #
31
+ # @example
32
+ # account.geo_location("Roma", "IT")
33
+ # account.geo_location("Via Conca del Naviglio", "Milano", "IT")
34
+ # account.geo_location( geoLocationSelector )
35
+ #
36
+ def geo_location(c1 = nil, c2 = nil, c3 = nil)
37
+ if c1.class != GeoLocationSelector
38
+ selector = GeoLocationSelector.new
39
+ selector.address do
40
+ if c3
41
+ address c1
42
+ city c2
43
+ country c3
44
+ else
45
+ city c1
46
+ country c2
47
+ end
48
+ end
49
+ else
50
+ selector = c1
51
+ end
52
+
53
+ soap_message = service.geo_location.get(credentials, selector.to_xml)
54
+ add_counters(soap_message.counters)
34
55
  # cost = REXML::XPath.first( soap_message.response, "//getResponse/rval/cost")
35
56
  # cost.text.to_i
36
57
  end
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -------------------------------------------------------------------------
3
+ # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ # -------------------------------------------------------------------------
24
+
25
+ module Sem4r
26
+
27
+ class GeoLocationSelector
28
+ include Sem4rSoap::SoapAttributes
29
+
30
+ attr_reader :addresses
31
+
32
+ def initialize(&block)
33
+ @addresses = []
34
+ if block_given?
35
+ block.arity < 1 ? instance_eval(&block) : block.call(self)
36
+ end
37
+ end
38
+
39
+ def address(address = nil, &block)
40
+ if address.nil? and block_given?
41
+ @addresses << Address.new(&block)
42
+ else
43
+ @addresses << address
44
+ end
45
+ end
46
+
47
+ def to_xml
48
+ xml = "<s:selector>"
49
+ @addresses.each do |address|
50
+ xml += address.to_xml("addresses")
51
+ end
52
+ xml += "</s:selector>"
53
+ xml
54
+ end
55
+
56
+ end
57
+ end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,8 +23,11 @@
22
23
  # -------------------------------------------------------------------
23
24
 
24
25
  module Sem4r
25
- class GeoLocationService
26
- include SoapCall
26
+
27
+ #
28
+ # @private
29
+ #
30
+ class GeoLocationService < Sem4rSoap::SoapServiceV2010
27
31
 
28
32
  def initialize(connector)
29
33
  @connector = connector
@@ -33,26 +37,15 @@ module Sem4r
33
37
 
34
38
  @sandbox_service_url = "https://adwords-sandbox.google.com/api/adwords/cm/v201008/GeoLocationService"
35
39
  @production_service_url = "https://adwords.google.com/api/adwords/cm/v201008/GeoLocationService"
40
+ init(@header_namespace, @service_namespace)
36
41
  end
37
42
 
38
- soap_call_v2010 :get
39
-
40
- ################
43
+ soap_call :get
41
44
 
42
45
  private
43
46
 
44
47
  def _get(xml)
45
- <<-EOFS
46
- <s:get>
47
- <s:selector>
48
- <addresses>
49
- <streetAddress>Via Nazionale,10</streetAddress>
50
- <cityName>Rome</cityName>
51
- <countryCode>IT</countryCode>
52
- </addresses>
53
- </s:selector>
54
- </s:get>
55
- EOFS
48
+ "<s:get>#{xml}</s:get>"
56
49
  end
57
50
 
58
51
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -27,13 +28,13 @@ module Sem4r
27
28
  module AccountInfoExtension
28
29
 
29
30
  def year_unit_cost(usage_type)
30
- now = Time.new
31
+ now = Time.new - 60 * 60 * 24 # - 1 day time in which timezone?
31
32
  selector = InfoSelector.new do
32
33
  usage_type usage_type
33
34
  min now.strftime("%Y0101") # first January
34
35
  max now.strftime("%Y%m%d")
35
36
  end
36
- soap_message = service.info.get(@credentials, selector.to_xml)
37
+ soap_message = service.info.get(credentials, selector.to_xml)
37
38
  add_counters( soap_message.counters )
38
39
  # cost = REXML::XPath.first( soap_message.response, "//getResponse/rval/cost")
39
40
  cost = soap_message.response.at_xpath("//getResponse/rval/cost")
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -72,7 +73,7 @@ module Sem4r
72
73
  # operator parameters.
73
74
 
74
75
  class InfoSelector
75
- include SoapAttributes
76
+ include Sem4rSoap::SoapAttributes
76
77
 
77
78
  enum :UsageTypes, [
78
79
  :FREE_USAGE_API_UNITS_PER_MONTH,
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,8 +23,11 @@
22
23
  # -------------------------------------------------------------------
23
24
 
24
25
  module Sem4r
25
- class InfoService
26
- include SoapCall
26
+
27
+ #
28
+ # @private
29
+ #
30
+ class InfoService < Sem4rSoap::SoapServiceV2010
27
31
 
28
32
  def initialize(connector)
29
33
  @connector = connector
@@ -32,9 +36,12 @@ module Sem4r
32
36
 
33
37
  @production_service_url = "https://adwords.google.com/api/adwords/info/v201008/InfoService"
34
38
  @sandbox_service_url = "https://adwords-sandbox.google.com/api/adwords/info/v201008/InfoService"
39
+ init(@header_namespace, @service_namespace)
35
40
  end
36
41
 
37
- soap_call_v2010 :get, :mutate => false
42
+ soap_call :get, :mutate => false
43
+
44
+ private
38
45
 
39
46
  def _unit_cost( usage_type )
40
47
  <<-EOFS
@@ -25,13 +25,30 @@
25
25
 
26
26
  module Sem4r
27
27
 
28
+ #
29
+ # Contains an operand. Operand can be everything that respond_to :to_xml and :xml
30
+ #
28
31
  class Operation
29
- include SoapAttributes
32
+ include Sem4rSoap::SoapAttributes
33
+
34
+ class << self
35
+ def add(operand)
36
+ self.new.add(operand)
37
+ end
38
+
39
+ def remove(operand)
40
+ self.new.remove(operand)
41
+ end
42
+
43
+ def set(operand)
44
+ self.new.set(operand)
45
+ end
46
+ end
30
47
 
31
48
  enum :Operations, [
32
- :ADD,
33
- :REMOVE,
34
- :SET]
49
+ :ADD,
50
+ :REMOVE,
51
+ :SET]
35
52
 
36
53
  attr_reader :operation_type
37
54
  g_accessor :operator
@@ -54,27 +71,29 @@ module Sem4r
54
71
  self
55
72
  end
56
73
 
57
- def to_xml(tag)
58
- if @operand == nil
59
- raise Sem4rError, "Missing Operand"
60
- end
74
+ def _xml(t)
75
+ raise Sem4rError, "Missing Operand" unless @operand
76
+ t.operator operator
77
+ @operand.xml(t, "operand")
78
+ end
61
79
 
62
- xml = ""
80
+ def xml(t, tag = nil)
81
+ raise Sem4rError, "Missing Operand" unless @operand
63
82
  if tag
64
- xml += "<#{tag} xsi:type='#{operation_type}' #{if @namespace then @namespace else '' end}>"
65
- # xsi:type="n1:ReportDefinitionOperation" xmlns:n1="https://adwords.google.com/api/adwords/cm/v201008"
83
+ attrs = {}
84
+ attrs = {'xsi:type'=> operation_type} if operation_type
85
+ attrs.merge! @attrs if @attrs
86
+ t.__send__(tag, attrs) { |t| _xml(t) }
87
+ else
88
+ _xml(t)
66
89
  end
67
- xml +=<<-EOS
68
- <operator>#{operator}</operator>
69
- #{@operand.to_xml('operand')}
70
- EOS
90
+ end
71
91
 
72
- if tag
73
- xml += "</#{tag}>"
74
- end
75
- xml
92
+ def to_xml(tag = "operations")
93
+ raise Sem4rError, "Missing Operand" unless @operand
94
+ xml(Builder::XmlMarkup.new, tag)
76
95
  end
77
96
 
78
97
  end
79
98
 
80
- end
99
+ end #module Sem4r
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,7 +20,6 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  module Sem4r
@@ -94,19 +94,23 @@ module Sem4r
94
94
  "#{@id}: '#{@name}'"
95
95
  end
96
96
 
97
- def to_xml(tag)
98
- builder = Builder::XmlMarkup.new
99
- builder.tag!(tag) do |t|
100
-
101
- t.id @id if @id
102
- t.reportName @name if @name
103
- t.reportType @type if @type
104
- t.dateRangeType @date_range if @date_range
105
- t.downloadFormat @format if @format
97
+ #
98
+ # @private
99
+ #
100
+ def _xml(t)
101
+ t.id @id if @id
106
102
 
103
+ if !fields.empty? or ( !!from and !!to )
107
104
  #TODO: non costruire selector se il contenuto e' vuoto utile per l'operazione di delete
108
105
  t.selector do |t|
109
106
  fields.each { |f| t.fields f}
107
+
108
+ # t.predicates do |t|
109
+ # t.field "AdGroupId"
110
+ # t.operator "EQUALS"
111
+ # t.values 1
112
+ # end
113
+
110
114
  if from and to
111
115
  t.dateRange do |t|
112
116
  t.min from
@@ -114,10 +118,32 @@ module Sem4r
114
118
  end
115
119
  end
116
120
  end
121
+ end
122
+
123
+ t.reportName @name if @name
124
+ t.reportType @type if @type
125
+ t.dateRangeType @date_range if @date_range
126
+ t.downloadFormat @format if @format
127
+ end
128
+
117
129
 
130
+ #
131
+ # Marshall to xml using a Builder::Markup
132
+ # @param [Builder::Markup]
133
+ #
134
+ def xml(t, tag = nil)
135
+ if tag
136
+ t.__send__(tag) { |t| _xml(t) }
137
+ else
138
+ _xml(t)
118
139
  end
119
140
  end
120
141
 
142
+ def to_xml(tag = "operand")
143
+ xml(Builder::XmlMarkup.new, tag)
144
+ end
145
+
146
+
121
147
  ###########################################################################
122
148
 
123
149
  def self.from_element(account, el)
@@ -149,15 +175,7 @@ module Sem4r
149
175
  end
150
176
 
151
177
  def delete
152
- soap_message = service.campaign.delete(credentials, @id)
153
- add_counters( soap_message.counters )
154
- @id = -1 # logical delete
155
- end
156
-
157
- ###########################################################################
158
-
159
- def empty?
160
- _ad_groups.empty?
178
+ @account.report_definition_delete(self)
161
179
  end
162
180
 
163
181
  end