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.
- data/Gemfile +13 -2
- data/Gemfile.lock +13 -7
- data/README.rdoc +44 -7
- data/Rakefile +2 -122
- data/VERSION.yml +1 -1
- data/bin/sem +1 -0
- data/examples_sem4r/01_get_account.rb +1 -0
- data/examples_sem4r/02_get_info.rb +1 -0
- data/examples_sem4r/03_list_ad.rb +1 -0
- data/examples_sem4r/04_list_keywords.rb +1 -0
- data/examples_sem4r/05_request_report.rb +25 -14
- data/examples_sem4r/{05_request_report_2010.rb → 06_request_report_definition.rb} +2 -4
- data/examples_sem4r/{06_create_campaigns.rb → 07_create_campaigns.rb} +1 -0
- data/examples_sem4r/{07_create_campaigns_block.rb → 08_create_campaigns_block.rb} +1 -0
- data/examples_sem4r/{07_create_campaigns_simple.rb → 09_create_campaigns_simple.rb} +1 -0
- data/examples_sem4r/{08_ad_params.rb → 10_ad_params.rb} +1 -0
- data/examples_sem4r/{09_targeting_idea.rb → 11_targeting_idea.rb} +1 -0
- data/examples_sem4r/{10_get_location.rb → 12_get_location.rb} +1 -0
- data/examples_sem4r/{11_submit_bulk_job.rb → 13_submit_bulk_job.rb} +1 -1
- data/examples_sem4r/{12_list_bulk_job.rb → 14_list_bulk_job.rb} +3 -0
- data/examples_sem4r/30_prune_empty_adgroup.rb +1 -0
- data/examples_sem4r/31_empty_accounts.rb +1 -0
- data/examples_sem4r/example_helper.rb +2 -1
- data/lib/sem4r/ad_group/ad_group.rb +22 -7
- data/lib/sem4r/ad_group/ad_group_bids.rb +1 -1
- data/lib/sem4r/ad_group/ad_group_service.rb +12 -5
- data/lib/sem4r/ad_group_ad/ad_group_ad.rb +1 -0
- data/lib/sem4r/ad_group_ad/ad_group_ad_operations.rb +1 -0
- data/lib/sem4r/ad_group_ad/ad_group_ad_service.rb +14 -9
- data/lib/sem4r/ad_group_ad/ad_group_mobile_ad.rb +16 -25
- data/lib/sem4r/ad_group_ad/ad_group_text_ad.rb +18 -14
- data/lib/sem4r/ad_group_criterion/ad_group_criterion.rb +27 -19
- data/lib/sem4r/ad_group_criterion/ad_group_criterion_bids.rb +2 -1
- data/lib/sem4r/ad_group_criterion/ad_group_criterion_operations.rb +1 -0
- data/lib/sem4r/ad_group_criterion/ad_group_criterion_service.rb +9 -4
- data/lib/sem4r/ad_group_criterion/criterion.rb +1 -0
- data/lib/sem4r/ad_group_criterion/criterion_keyword.rb +1 -0
- data/lib/sem4r/ad_group_criterion/criterion_placement.rb +1 -0
- data/lib/sem4r/ad_param/ad_param.rb +24 -8
- data/lib/sem4r/ad_param/ad_param_service.rb +8 -5
- data/lib/sem4r/adwords.rb +232 -76
- data/lib/sem4r/base.rb +1 -1
- data/lib/sem4r/bulk_mutate_job/bulk_mutate_job.rb +41 -35
- data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_account_extension.rb +49 -15
- data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_selector.rb +29 -20
- data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_service.rb +13 -14
- data/lib/sem4r/bulk_mutate_job/job_operations.rb +1 -1
- data/lib/sem4r/campaign/campaign.rb +1 -0
- data/lib/sem4r/campaign/campaign_account_extension.rb +2 -1
- data/lib/sem4r/campaign/campaign_service.rb +9 -5
- data/lib/sem4r/credentials.rb +11 -5
- data/lib/sem4r/geo_location/address.rb +56 -0
- data/lib/sem4r/geo_location/geo_location_account_extension.rb +27 -6
- data/lib/sem4r/geo_location/geo_location_selector.rb +57 -0
- data/lib/sem4r/geo_location/geo_location_service.rb +9 -16
- data/lib/sem4r/info/info_account_extension.rb +3 -2
- data/lib/sem4r/info/info_selector.rb +2 -1
- data/lib/sem4r/info/info_service.rb +10 -3
- data/lib/sem4r/operation.rb +39 -20
- data/lib/sem4r/report_definition/report_definition.rb +37 -19
- data/lib/sem4r/report_definition/report_definition_account_extension.rb +66 -16
- data/lib/sem4r/report_definition/report_definition_operation.rb +2 -2
- data/lib/sem4r/report_definition/report_definition_selector.rb +1 -1
- data/lib/sem4r/report_definition/report_definition_service.rb +11 -7
- data/lib/sem4r/report_definition/report_field.rb +3 -2
- data/lib/sem4r/sem4r_templates.rb +77 -0
- data/lib/sem4r/{services/service.rb → service.rb} +23 -23
- data/lib/sem4r/targeting_idea/targeting_idea.rb +4 -4
- data/lib/sem4r/targeting_idea/targeting_idea_account_extension.rb +1 -1
- data/lib/sem4r/targeting_idea/targeting_idea_selector.rb +6 -6
- data/lib/sem4r/targeting_idea/targeting_idea_service.rb +7 -5
- data/lib/sem4r/v13_account/account_account_extension.rb +7 -10
- data/lib/sem4r/v13_account/account_service.rb +10 -4
- data/lib/sem4r/v13_account/billing_address.rb +2 -2
- data/lib/sem4r/v13_report/report_service.rb +11 -9
- data/lib/sem4r.rb +46 -31
- data/lib/{sem4r/cli → sem4r_cli}/cli_helpers.rb +3 -2
- data/lib/{sem4r/cli/cli_command.rb → sem4r_cli/cli_mini_framework.rb} +77 -32
- data/lib/{sem4r/cli/cli_common_args.rb → sem4r_cli/cli_sem.rb} +177 -157
- data/lib/{sem4r/cli/commands/cli_list_ads.rb → sem4r_cli/commands/cli_ads.rb} +7 -9
- data/lib/sem4r_cli/commands/cli_campaign.rb +69 -0
- data/lib/{sem4r/cli/commands/cli_list_client.rb → sem4r_cli/commands/cli_clients.rb} +2 -2
- data/lib/{sem4r/cli → sem4r_cli}/commands/cli_ideas.rb +35 -27
- data/lib/{sem4r/cli → sem4r_cli}/commands/cli_info.rb +3 -4
- data/lib/{sem4r/cli/commands/cli_repdef.rb → sem4r_cli/commands/cli_job.rb} +57 -55
- data/lib/{sem4r/cli/commands/cli_list_keywords.rb → sem4r_cli/commands/cli_keywords.rb} +14 -13
- data/lib/sem4r_cli/commands/cli_profile.rb +138 -0
- data/lib/{sem4r/cli/commands/cli_report.rb → sem4r_cli/commands/cli_repdef.rb} +67 -20
- data/lib/{sem4r/cli/commands/cli_request_report.rb → sem4r_cli/commands/cli_report.rb} +82 -19
- data/lib/sem4r_cli.rb +5 -7
- data/lib/sem4r_soap/http_connector.rb +206 -0
- data/lib/{soap_helpers → sem4r_soap}/soap_attributes.rb +8 -3
- data/lib/{sem4r/services → sem4r_soap}/soap_dumper.rb +36 -20
- data/lib/{sem4r/services → sem4r_soap}/soap_error.rb +5 -2
- data/lib/sem4r_soap/soap_response.rb +75 -0
- data/lib/sem4r_soap/soap_service.rb +137 -0
- data/lib/{sem4r/cli/cli_sem.rb → sem4r_soap/soap_service_v13.rb} +27 -28
- data/lib/sem4r_soap/soap_service_v2010.rb +80 -0
- data/lib/sem4r_soap.rb +17 -0
- data/sem4r.gemspec +93 -58
- data/spec/build_fixtures.rb +49 -42
- data/spec/fixtures/password.example.yml +3 -0
- data/spec/fixtures/sem4r.example.yml +6 -0
- data/spec/fixtures/{services/error.xml → soap_error.xml} +0 -0
- data/spec/fixtures/soap_error2.xml +29 -0
- data/spec/helpers/dump_interceptor.rb +90 -0
- data/spec/helpers/fixtures_bulk_mutate_job.rb +48 -0
- data/spec/helpers/fixtures_geo_location.rb +45 -0
- data/{lib/sem4r/campaign_criterion/campaign_criterion_service.rb → spec/helpers/fixtures_info.rb} +10 -6
- data/spec/helpers/fixtures_report_definition.rb +65 -0
- data/spec/{rspec_hash.rb → helpers/rspec_hash.rb} +1 -0
- data/spec/{rspec_matchers.rb → helpers/rspec_matchers.rb} +46 -19
- data/spec/{rspec_sem4r_helper.rb → helpers/rspec_sem4r_helper.rb} +19 -16
- data/spec/{sem4r_stubs.rb → helpers/sem4r_stubs.rb} +5 -4
- data/spec/rspec_helper.rb +4 -4
- data/spec/sem4r/account_spec.rb +2 -3
- data/spec/sem4r/ad_group/ad_group_service_spec.rb +1 -1
- data/spec/sem4r/ad_group/ad_group_spec.rb +1 -1
- data/spec/sem4r/ad_group_ad/ad_group_ad_operation_spec.rb +3 -3
- data/spec/sem4r/adwords_spec.rb +62 -39
- data/{lib/sem4r/cli/commands/cli_list_campaign.rb → spec/sem4r/bulk_mutate_job/bulk_mutate_job_selector_spec.rb} +14 -11
- data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_service_spec.rb +2 -3
- data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_spec.rb +23 -17
- data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-req.xml +35 -0
- data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-res.xml +417 -0
- data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-req.xml +106 -0
- data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-res.xml +48 -0
- data/spec/sem4r/bulk_mutate_job/job_operation_spec.rb +5 -7
- data/spec/sem4r/campaign/campaign_service_spec.rb +2 -2
- data/spec/sem4r/credentials_spec.rb +10 -8
- data/spec/sem4r/geo_location/address_spec.rb +62 -0
- data/spec/sem4r/geo_location/fixtures/get-req.xml +42 -0
- data/spec/sem4r/geo_location/fixtures/get-res.xml +60 -0
- data/spec/sem4r/info/fixtures/get-req.xml +34 -0
- data/spec/sem4r/info/fixtures/get-res.xml +27 -0
- data/spec/sem4r/nokogiri_parsing_spec.rb +1 -0
- data/spec/sem4r/operation_spec.rb +72 -0
- data/spec/sem4r/report_definition/fixtures/get-list-repdef-req.xml +22 -0
- data/spec/sem4r/report_definition/fixtures/get-list-repdef-res.xml +73 -0
- data/spec/sem4r/report_definition/fixtures/getReportFields-req.xml +24 -0
- data/spec/sem4r/report_definition/fixtures/getReportFields-res.xml +1199 -0
- data/spec/sem4r/report_definition/fixtures/mutate-add-report-req.xml +63 -0
- data/spec/sem4r/report_definition/fixtures/mutate-add-report-res.xml +68 -0
- data/spec/sem4r/report_definition/report_definition_service_spec.rb +5 -5
- data/spec/sem4r/report_definition/report_definition_spec.rb +28 -43
- data/{lib/sem4r/cli/commands/cli_list_report.rb → spec/sem4r/report_definition/report_field_spec.rb} +12 -10
- data/spec/sem4r/rexml_parsing_spec.rb +1 -0
- data/spec/sem4r/{services/service_spec.rb → service_spec.rb} +1 -1
- data/spec/sem4r/targeting_idea/targeting_idea_selector_spec.rb +1 -1
- data/spec/sem4r/targeting_idea/targeting_idea_service_spec.rb +1 -1
- data/spec/sem4r/targeting_idea/targeting_idea_spec.rb +1 -1
- data/spec/sem4r/v13_account/account_service_spec.rb +2 -2
- data/spec/sem4r/v13_report/report_service_spec.rb +2 -2
- data/spec/{sem4r/cli → sem4r_cli}/cli_spec.rb +22 -27
- data/spec/{soap_helpers → sem4r_soap}/soap_attributes_spec.rb +3 -3
- data/spec/{sem4r/services/soap_message_v13_spec.rb → sem4r_soap/soap_response_spec.rb} +10 -15
- data/spec/{sem4r/services/soap_call_spec.rb → sem4r_soap/soap_service_spec.rb} +35 -54
- data/tasks/jeweler.rake +66 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/sem4r.rake +25 -0
- data/tasks/yard.rake +31 -0
- metadata +173 -76
- data/lib/sem4r/ad_extension_override/ad_extension_override_service.rb +0 -30
- data/lib/sem4r/api_counters.rb +0 -8
- data/lib/sem4r/campaign_target/campaign_target_service.rb +0 -30
- data/lib/sem4r/cli/commands/cli_download_report.rb +0 -82
- data/lib/sem4r/services/http_connector.rb +0 -93
- data/lib/sem4r/services/soap_call.rb +0 -122
- data/lib/sem4r/services/soap_connector.rb +0 -139
- data/lib/sem4r/services/soap_message_v13.rb +0 -135
- data/lib/sem4r/services/soap_message_v2010.rb +0 -184
- data/lib/sem4r/v13_traffic_estimator/traffic_estimator_service.rb +0 -30
- data/spec/aggregates_rspec_helper.rb +0 -59
- data/spec/sem4r/report_definition/fixtures/mutate_add-req.xml +0 -24
- 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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
40
|
-
|
|
42
|
+
soap_call :get, :mutate => false
|
|
43
|
+
soap_call :mutate
|
|
41
44
|
|
|
42
45
|
private
|
|
43
46
|
|
|
44
|
-
def
|
|
45
|
-
"<get xmlns=\"#{@service_namespace}\"
|
|
47
|
+
def _get(xml)
|
|
48
|
+
"<get xmlns=\"#{@service_namespace}\">#{xml}</get>";
|
|
46
49
|
end
|
|
47
50
|
|
|
48
|
-
def _mutate(
|
|
49
|
-
|
|
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
|
#
|
|
@@ -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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
soap_call :all, :mutate => false
|
|
42
|
+
soap_call :create
|
|
43
|
+
soap_call :delete
|
|
40
44
|
|
|
41
45
|
private
|
|
42
46
|
|
data/lib/sem4r/credentials.rb
CHANGED
|
@@ -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
|
-
|
|
83
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
################
|
|
43
|
+
soap_call :get
|
|
41
44
|
|
|
42
45
|
private
|
|
43
46
|
|
|
44
47
|
def _get(xml)
|
|
45
|
-
|
|
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(
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
42
|
+
soap_call :get, :mutate => false
|
|
43
|
+
|
|
44
|
+
private
|
|
38
45
|
|
|
39
46
|
def _unit_cost( usage_type )
|
|
40
47
|
<<-EOFS
|
data/lib/sem4r/operation.rb
CHANGED
|
@@ -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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
80
|
+
def xml(t, tag = nil)
|
|
81
|
+
raise Sem4rError, "Missing Operand" unless @operand
|
|
63
82
|
if tag
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
68
|
-
<operator>#{operator}</operator>
|
|
69
|
-
#{@operand.to_xml('operand')}
|
|
70
|
-
EOS
|
|
90
|
+
end
|
|
71
91
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
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
|