sem4r 0.1.2 → 0.1.3

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.
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