sem4r 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +22 -0
- data/README.rdoc +74 -0
- data/Rakefile +126 -0
- data/VERSION.yml +5 -0
- data/bin/sem +34 -0
- data/config/sem4r.example.yml +51 -0
- data/examples_blog/2009-11-29-hello-world.rb +12 -0
- data/examples_blog/2009-12-12-create-campaign.rb +29 -0
- data/examples_blog/2010-02-06-constants-scope.rb +8 -0
- data/examples_blog/2010-02-07-ad-parameters.rb +47 -0
- data/examples_sem4r/01_get_account.rb +37 -0
- data/examples_sem4r/02_get_info.rb +32 -0
- data/examples_sem4r/03_list_ad.rb +47 -0
- data/examples_sem4r/04_list_keywords.rb +54 -0
- data/examples_sem4r/05_request_report.rb +51 -0
- data/examples_sem4r/05_request_report_2010.rb +40 -0
- data/examples_sem4r/06_create_campaigns.rb +86 -0
- data/examples_sem4r/07_create_campaigns_block.rb +99 -0
- data/examples_sem4r/07_create_campaigns_simple.rb +65 -0
- data/examples_sem4r/08_ad_params.rb +70 -0
- data/examples_sem4r/09_targeting_idea.rb +59 -0
- data/examples_sem4r/10_get_location.rb +28 -0
- data/examples_sem4r/11_submit_bulk_job.rb +82 -0
- data/examples_sem4r/12_list_bulk_job.rb +29 -0
- data/examples_sem4r/30_prune_empty_adgroup.rb +50 -0
- data/examples_sem4r/31_empty_accounts.rb +40 -0
- data/examples_sem4r/example_helper.rb +115 -0
- data/lib/sem4r/account.rb +349 -0
- data/lib/sem4r/ad_extension_override/ad_extension_override_service.rb +30 -0
- data/lib/sem4r/ad_group/ad_group.rb +340 -0
- data/lib/sem4r/ad_group/ad_group_bids.rb +170 -0
- data/lib/sem4r/ad_group/ad_group_service.rb +75 -0
- data/lib/sem4r/ad_group/mobile_ad_image.rb +33 -0
- data/lib/sem4r/ad_group_ad/ad_group_ad.rb +98 -0
- data/lib/sem4r/ad_group_ad/ad_group_ad_operations.rb +38 -0
- data/lib/sem4r/ad_group_ad/ad_group_ad_service.rb +56 -0
- data/lib/sem4r/ad_group_ad/ad_group_mobile_ad.rb +137 -0
- data/lib/sem4r/ad_group_ad/ad_group_text_ad.rb +98 -0
- data/lib/sem4r/ad_group_criterion/ad_group_criterion.rb +144 -0
- data/lib/sem4r/ad_group_criterion/ad_group_criterion_bids.rb +115 -0
- data/lib/sem4r/ad_group_criterion/ad_group_criterion_operations.rb +35 -0
- data/lib/sem4r/ad_group_criterion/ad_group_criterion_service.rb +58 -0
- data/lib/sem4r/ad_group_criterion/criterion.rb +67 -0
- data/lib/sem4r/ad_group_criterion/criterion_keyword.rb +80 -0
- data/lib/sem4r/ad_group_criterion/criterion_placement.rb +66 -0
- data/lib/sem4r/ad_param/ad_param.rb +96 -0
- data/lib/sem4r/ad_param/ad_param_operation.rb +34 -0
- data/lib/sem4r/ad_param/ad_param_service.rb +59 -0
- data/lib/sem4r/adwords.rb +242 -0
- data/lib/sem4r/api_counters.rb +7 -0
- data/lib/sem4r/base.rb +43 -0
- data/lib/sem4r/bulk_mutate_job/bulk_mutate_job.rb +108 -0
- data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_selector.rb +56 -0
- data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_service.rb +57 -0
- data/lib/sem4r/bulk_mutate_job/job_operations.rb +35 -0
- data/lib/sem4r/campaign/campaign.rb +193 -0
- data/lib/sem4r/campaign/campaign_service.rb +91 -0
- data/lib/sem4r/campaign_criterion/campaign_criterion_service.rb +30 -0
- data/lib/sem4r/campaign_target/campaign_target_service.rb +30 -0
- data/lib/sem4r/cli/cli_command.rb +101 -0
- data/lib/sem4r/cli/cli_commands.rb +60 -0
- data/lib/sem4r/cli/cli_common_args.rb +293 -0
- data/lib/sem4r/cli/cli_download_report.rb +81 -0
- data/lib/sem4r/cli/cli_helpers.rb +57 -0
- data/lib/sem4r/cli/cli_ideas.rb +100 -0
- data/lib/sem4r/cli/cli_list_ads.rb +74 -0
- data/lib/sem4r/cli/cli_list_keywords.rb +76 -0
- data/lib/sem4r/cli/cli_request_report.rb +104 -0
- data/lib/sem4r/cli/cli_sem.rb +64 -0
- data/lib/sem4r/common/operation.rb +78 -0
- data/lib/sem4r/credentials.rb +86 -0
- data/lib/sem4r/extensions.rb +62 -0
- data/lib/sem4r/geo_location/geo_location_service.rb +59 -0
- data/lib/sem4r/info/info_service.rb +115 -0
- data/lib/sem4r/report_definition/report_definition.rb +104 -0
- data/lib/sem4r/report_definition/report_definition_operation.rb +34 -0
- data/lib/sem4r/report_definition/report_definition_selector.rb +31 -0
- data/lib/sem4r/report_definition/report_definition_service.rb +55 -0
- data/lib/sem4r/sem4r_error.rb +28 -0
- data/lib/sem4r/services/service.rb +74 -0
- data/lib/sem4r/services/soap_call.rb +100 -0
- data/lib/sem4r/services/soap_connector.rb +284 -0
- data/lib/sem4r/services/soap_error.rb +38 -0
- data/lib/sem4r/services/soap_message_v13.rb +129 -0
- data/lib/sem4r/services/soap_message_v2009.rb +170 -0
- data/lib/sem4r/soap_attributes.rb +141 -0
- data/lib/sem4r/targeting_idea/targeting_idea.rb +158 -0
- data/lib/sem4r/targeting_idea/targeting_idea_selector.rb +200 -0
- data/lib/sem4r/targeting_idea/targeting_idea_service.rb +51 -0
- data/lib/sem4r/v13_account/account_service.rb +54 -0
- data/lib/sem4r/v13_account/billing_address.rb +67 -0
- data/lib/sem4r/v13_report/report.rb +185 -0
- data/lib/sem4r/v13_report/report_job.rb +51 -0
- data/lib/sem4r/v13_report/report_service.rb +89 -0
- data/lib/sem4r/v13_traffic_estimator/traffic_estimator_service.rb +30 -0
- data/lib/sem4r.rb +142 -0
- data/lib/sem4r_cli.rb +40 -0
- data/sem4r.gemspec +247 -0
- data/spec/aggregates_spec_helper.rb +59 -0
- data/spec/fixtures/sem4r.example.yml +26 -0
- data/spec/fixtures/services/ad_group/get-first-req.xml +28 -0
- data/spec/fixtures/services/ad_group/get-first-res.xml +91 -0
- data/spec/fixtures/services/ad_group/get-manual-cpm-bids-req.xml +106 -0
- data/spec/fixtures/services/ad_group/get-manual-cpm-bids-res.xml +75 -0
- data/spec/fixtures/services/ad_group/mutate_add-req.xml +52 -0
- data/spec/fixtures/services/ad_group/mutate_add-res.xml +33 -0
- data/spec/fixtures/services/ad_group_ad/get_mobile_ad-req.xml +28 -0
- data/spec/fixtures/services/ad_group_ad/get_mobile_ad-res.xml +194 -0
- data/spec/fixtures/services/ad_group_ad/get_text_ad-req.xml +29 -0
- data/spec/fixtures/services/ad_group_ad/get_text_ad-res.xml +55 -0
- data/spec/fixtures/services/ad_group_ad/mutate_add_mobile_ad-req.xml +50 -0
- data/spec/fixtures/services/ad_group_ad/mutate_add_mobile_ad-res.xml +42 -0
- data/spec/fixtures/services/ad_group_ad/mutate_add_text_ad-req.xml +37 -0
- data/spec/fixtures/services/ad_group_ad/mutate_add_text_ad-res.xml +32 -0
- data/spec/fixtures/services/ad_group_ad/mutate_add_two_criterions-req.xml +83 -0
- data/spec/fixtures/services/ad_group_ad/mutate_add_two_criterions-res.xml +95 -0
- data/spec/fixtures/services/ad_group_criterion/get-req.xml +28 -0
- data/spec/fixtures/services/ad_group_criterion/get-res.xml +242 -0
- data/spec/fixtures/services/ad_group_criterion/mutate_add_criterion_keyword-req.xml +48 -0
- data/spec/fixtures/services/ad_group_criterion/mutate_add_criterion_keyword-res.xml +47 -0
- data/spec/fixtures/services/ad_group_criterion/mutate_add_criterion_placement-req.xml +35 -0
- data/spec/fixtures/services/ad_group_criterion/mutate_add_criterion_placement-res.xml +32 -0
- data/spec/fixtures/services/ad_group_criterion/mutate_add_negative_keyword-req.xml +37 -0
- data/spec/fixtures/services/ad_group_criterion/mutate_add_negative_keyword-res.xml +51 -0
- data/spec/fixtures/services/ad_param/mutate_set-req.xml +43 -0
- data/spec/fixtures/services/ad_param/mutate_set-res.xml +29 -0
- data/spec/fixtures/services/bulk_mutate_job/get-req.xml +36 -0
- data/spec/fixtures/services/bulk_mutate_job/get-res.xml +54 -0
- data/spec/fixtures/services/bulk_mutate_job/mutate-req.xml +69 -0
- data/spec/fixtures/services/bulk_mutate_job/mutate-res.xml +48 -0
- data/spec/fixtures/services/campaign/get-req.xml +37 -0
- data/spec/fixtures/services/campaign/get-res.xml +1986 -0
- data/spec/fixtures/services/campaign/mutate_add-req.xml +37 -0
- data/spec/fixtures/services/campaign/mutate_add-res.xml +42 -0
- data/spec/fixtures/services/error.xml +28 -0
- data/spec/fixtures/services/info/get_unit_count-req.xml +30 -0
- data/spec/fixtures/services/info/get_unit_count-res.xml +29 -0
- data/spec/fixtures/services/report_definition/mutate_add-req.xml +24 -0
- data/spec/fixtures/services/report_definition/mutate_add-req_orig.xml +45 -0
- data/spec/fixtures/services/targeting_idea/get-req-all-options.xml +57 -0
- data/spec/fixtures/services/targeting_idea/get-req.xml +60 -0
- data/spec/fixtures/services/targeting_idea/get-res.xml +3601 -0
- data/spec/fixtures/services/v13_account/get_account_info-req.xml +23 -0
- data/spec/fixtures/services/v13_account/get_account_info-res.xml +54 -0
- data/spec/fixtures/services/v13_account/get_client_accounts-req.xml +22 -0
- data/spec/fixtures/services/v13_account/get_client_accounts-res.xml +37 -0
- data/spec/fixtures/services/v13_report/get_all_jobs-req.xml +21 -0
- data/spec/fixtures/services/v13_report/get_all_jobs-res.xml +109 -0
- data/spec/fixtures/services/v13_report/schedule_report_job-req.xml +56 -0
- data/spec/fixtures/services/v13_report/schedule_report_job-res.xml +24 -0
- data/spec/sem4r/account_spec.rb +86 -0
- data/spec/sem4r/ad_group/ad_group_bids_spec.rb +67 -0
- data/spec/sem4r/ad_group/ad_group_service_spec.rb +66 -0
- data/spec/sem4r/ad_group/ad_group_spec.rb +212 -0
- data/spec/sem4r/ad_group_ad/ad_group_ad_operation_spec.rb +88 -0
- data/spec/sem4r/ad_group_ad/ad_group_ad_service_spec.rb +55 -0
- data/spec/sem4r/ad_group_ad/ad_group_ad_spec.rb +173 -0
- data/spec/sem4r/ad_group_criterion/ad_group_criterion_bids_spec.rb +60 -0
- data/spec/sem4r/ad_group_criterion/ad_group_criterion_service_spec.rb +55 -0
- data/spec/sem4r/ad_group_criterion/ad_group_criterion_spec.rb +103 -0
- data/spec/sem4r/ad_group_criterion/criterion_spec.rb +85 -0
- data/spec/sem4r/ad_param/ad_param_service_spec.rb +55 -0
- data/spec/sem4r/ad_param/ad_param_spec.rb +59 -0
- data/spec/sem4r/adwords_spec.rb +110 -0
- data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_service_spec.rb +63 -0
- data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_spec.rb +69 -0
- data/spec/sem4r/bulk_mutate_job/job_operation_spec.rb +48 -0
- data/spec/sem4r/campaign/campaign_service_spec.rb +66 -0
- data/spec/sem4r/campaign/campaign_spec.rb +105 -0
- data/spec/sem4r/cli/cli_spec.rb +71 -0
- data/spec/sem4r/credentials_spec.rb +65 -0
- data/spec/sem4r/report_definition/report_definition_service_spec.rb +44 -0
- data/spec/sem4r/report_definition/report_definition_spec.rb +105 -0
- data/spec/sem4r/rexml_parsing_spec.rb +103 -0
- data/spec/sem4r/services/service_spec.rb +36 -0
- data/spec/sem4r/services/soap_call_spec.rb +115 -0
- data/spec/sem4r/services/soap_message_v13_spec.rb +54 -0
- data/spec/sem4r/soap_attributes_spec.rb +116 -0
- data/spec/sem4r/targeting_idea/targeting_idea_selector_spec.rb +120 -0
- data/spec/sem4r/targeting_idea/targeting_idea_service_spec.rb +44 -0
- data/spec/sem4r/targeting_idea/targeting_idea_spec.rb +53 -0
- data/spec/sem4r/v13_account/account_service_spec.rb +60 -0
- data/spec/sem4r/v13_report/report_service_spec.rb +104 -0
- data/spec/sem4r/v13_report/report_spec.rb +79 -0
- data/spec/sem4r_spec_helper.rb +353 -0
- data/spec/spec_helper.rb +12 -0
- metadata +375 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#
|
|
23
|
+
# -------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
module Sem4r
|
|
26
|
+
|
|
27
|
+
class CliRequestReport < CliCommand
|
|
28
|
+
|
|
29
|
+
def self.command
|
|
30
|
+
"request"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.description
|
|
34
|
+
"schedule a report"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def initialize(account)
|
|
38
|
+
@account = account
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def command_opt_parser(options)
|
|
42
|
+
opt_parser = OptionParser.new
|
|
43
|
+
opt_parser.banner = "Usage #{self.class.command} [command_options ] <report_id>"
|
|
44
|
+
opt_parser.separator ""
|
|
45
|
+
opt_parser.separator "#{self.class.description}"
|
|
46
|
+
opt_parser.on("-h", "--help", "show this message") do
|
|
47
|
+
puts opt_parser
|
|
48
|
+
options.exit = true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def parse_and_run(argv)
|
|
53
|
+
options = OpenStruct.new
|
|
54
|
+
rest = command_opt_parser(options).parse( argv )
|
|
55
|
+
if options.exit
|
|
56
|
+
return false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
report = @account.report do
|
|
60
|
+
name 'boh'
|
|
61
|
+
type 'Url'
|
|
62
|
+
aggregation 'Daily'
|
|
63
|
+
cross_client true
|
|
64
|
+
zero_impression true
|
|
65
|
+
|
|
66
|
+
start_day '2010-01-01'
|
|
67
|
+
end_day '2010-01-30'
|
|
68
|
+
|
|
69
|
+
column "CustomerName"
|
|
70
|
+
column "ExternalCustomerId"
|
|
71
|
+
column "CampaignStatus"
|
|
72
|
+
column "Campaign"
|
|
73
|
+
column "CampaignId"
|
|
74
|
+
column "AdGroup"
|
|
75
|
+
column "AdGroupId"
|
|
76
|
+
column "AdGroupStatus"
|
|
77
|
+
column "QualityScore"
|
|
78
|
+
column "FirstPageCpc"
|
|
79
|
+
column "Keyword"
|
|
80
|
+
column "KeywordId"
|
|
81
|
+
column "KeywordTypeDisplay"
|
|
82
|
+
column "DestinationURL"
|
|
83
|
+
column "Impressions"
|
|
84
|
+
column "Clicks"
|
|
85
|
+
column "CTR"
|
|
86
|
+
column "CPC"
|
|
87
|
+
column "MaximumCPC"
|
|
88
|
+
column "Cost"
|
|
89
|
+
column "AveragePosition"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
unless report.validate
|
|
93
|
+
puts "report not valid"
|
|
94
|
+
exit
|
|
95
|
+
end
|
|
96
|
+
puts "scheduled job"
|
|
97
|
+
job = report.schedule
|
|
98
|
+
job.wait(5) { |report, status| puts "status #{status}" }
|
|
99
|
+
report.download("test_report.xml")
|
|
100
|
+
account.adwords.p_counters
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# -------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
# -------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
# stdlib
|
|
25
|
+
|
|
26
|
+
module Sem4r
|
|
27
|
+
|
|
28
|
+
class CliSem
|
|
29
|
+
|
|
30
|
+
def self.run
|
|
31
|
+
cli = self.new
|
|
32
|
+
cli.parse_and_run(ARGV)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def parse_and_run( argv )
|
|
36
|
+
common_args, command, command_args = CliCommand.split_args(argv)
|
|
37
|
+
|
|
38
|
+
# $stderr.puts "debug -------------------"
|
|
39
|
+
# $stderr.puts "common_args: #{common_args}"
|
|
40
|
+
# $stderr.puts "command: #{command}"
|
|
41
|
+
# $stderr.puts "command_args: #{command_args}"
|
|
42
|
+
# $stderr.puts "debug -------------------"
|
|
43
|
+
|
|
44
|
+
cli_common_args = CliCommonArgs.new
|
|
45
|
+
success = cli_common_args.parse_and_run(common_args)
|
|
46
|
+
return false unless success
|
|
47
|
+
|
|
48
|
+
if command.nil?
|
|
49
|
+
puts "missing command try sem -h for help"
|
|
50
|
+
return false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
begin
|
|
54
|
+
cmd = CliCommand.commands[command].new(cli_common_args)
|
|
55
|
+
return cmd.parse_and_run(command_args)
|
|
56
|
+
rescue Sem4rError
|
|
57
|
+
puts "I am so sorry! Something went wrong! (exception #{$!.to_s})"
|
|
58
|
+
return false
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#
|
|
23
|
+
# -------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
module Sem4r
|
|
26
|
+
|
|
27
|
+
class Operation
|
|
28
|
+
include SoapAttributes
|
|
29
|
+
|
|
30
|
+
enum :Operations, [
|
|
31
|
+
:ADD,
|
|
32
|
+
:REMOVE,
|
|
33
|
+
:SET]
|
|
34
|
+
|
|
35
|
+
attr_reader :operation_type
|
|
36
|
+
g_accessor :operator
|
|
37
|
+
|
|
38
|
+
def add(operand)
|
|
39
|
+
operator "ADD"
|
|
40
|
+
@operand = operand
|
|
41
|
+
self
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def remove(operand)
|
|
45
|
+
operator "REMOVE"
|
|
46
|
+
@operand = operand
|
|
47
|
+
self
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def set(operand)
|
|
51
|
+
operator "SET"
|
|
52
|
+
@operand = operand
|
|
53
|
+
self
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def to_xml(tag)
|
|
57
|
+
if @operand == nil
|
|
58
|
+
raise Sem4rError, "Missing Operand"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
xml = ""
|
|
62
|
+
if tag
|
|
63
|
+
xml += "<#{tag} xsi:type='#{operation_type}'>"
|
|
64
|
+
end
|
|
65
|
+
xml +=<<-EOS
|
|
66
|
+
<operator>#{operator}</operator>
|
|
67
|
+
#{@operand.to_xml('operand')}
|
|
68
|
+
EOS
|
|
69
|
+
|
|
70
|
+
if tag
|
|
71
|
+
xml += "</#{tag}>"
|
|
72
|
+
end
|
|
73
|
+
xml
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# -------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
# -------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
module Sem4r
|
|
25
|
+
|
|
26
|
+
class Credentials
|
|
27
|
+
|
|
28
|
+
attr_reader :environment
|
|
29
|
+
attr_reader :email
|
|
30
|
+
attr_reader :password
|
|
31
|
+
attr_reader :client_email
|
|
32
|
+
attr_reader :developer_token
|
|
33
|
+
attr_reader :useragent
|
|
34
|
+
|
|
35
|
+
def mutable?; @mutable; end
|
|
36
|
+
def sandbox?; @environment != "production" end
|
|
37
|
+
def production?; !sandbox?; end
|
|
38
|
+
|
|
39
|
+
def initialize( opts, client_email = nil )
|
|
40
|
+
case opts
|
|
41
|
+
when Hash
|
|
42
|
+
@environment= opts[:environment].dup.freeze
|
|
43
|
+
@email= opts[:email].dup.freeze
|
|
44
|
+
@password= opts[:password].dup.freeze
|
|
45
|
+
@useragent= "Sem4r Adwords Ruby Client Library (http://github.com/sem4r/sem4r)"
|
|
46
|
+
@developer_token= opts[:developer_token].dup.freeze
|
|
47
|
+
@mutable= opts[:mutable] ? true : false
|
|
48
|
+
when Credentials
|
|
49
|
+
@credentials = opts
|
|
50
|
+
@environment= @credentials.environment
|
|
51
|
+
@email= @credentials.email
|
|
52
|
+
@password= @credentials.password
|
|
53
|
+
@useragent= @credentials.useragent
|
|
54
|
+
@developer_token= @credentials.developer_token
|
|
55
|
+
@mutable= @credentials.mutable?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if client_email
|
|
59
|
+
@client_email = client_email.dup.freeze
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_s
|
|
64
|
+
if @client_email
|
|
65
|
+
"client account: #{@email} - #{@client_email} (#{@mutable ? "mutable" : "read only"})"
|
|
66
|
+
else
|
|
67
|
+
"master account: #{@email} (#{@mutable ? "mutable" : "read only"})"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def connector=(connector)
|
|
72
|
+
@connector= connector
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def authentication_token
|
|
76
|
+
return @authentication_token if @authentication_token
|
|
77
|
+
if @credentials
|
|
78
|
+
return @authentication_token = @credentials.authentication_token
|
|
79
|
+
end
|
|
80
|
+
raise "no connector in credentials! use credentials.connector=" unless @connector
|
|
81
|
+
@authentication_token = @connector.authentication_token(@email, @password)
|
|
82
|
+
@authentication_token
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Sem4r #:nodoc:
|
|
2
|
+
module CoreExtensions #:nodoc:
|
|
3
|
+
module Hash #:nodoc:
|
|
4
|
+
# Return a new hash with all keys converted to strings.
|
|
5
|
+
def stringify_keys
|
|
6
|
+
inject({}) do |options, (key, value)|
|
|
7
|
+
options[key.to_s] = value
|
|
8
|
+
options
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Destructively convert all keys to strings.
|
|
13
|
+
def stringify_keys!
|
|
14
|
+
keys.each do |key|
|
|
15
|
+
self[key.to_s] = delete(key)
|
|
16
|
+
end
|
|
17
|
+
self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Return a new hash with all keys converted to symbols.
|
|
21
|
+
def symbolize_keys
|
|
22
|
+
inject({}) do |options, (key, value)|
|
|
23
|
+
options[(key.to_sym rescue key) || key] = value
|
|
24
|
+
options
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Destructively convert all keys to symbols.
|
|
29
|
+
def symbolize_keys!
|
|
30
|
+
self.replace(self.symbolize_keys)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
alias_method :to_options, :symbolize_keys
|
|
34
|
+
alias_method :to_options!, :symbolize_keys!
|
|
35
|
+
|
|
36
|
+
# Validate all keys in a hash match *valid keys, raising ArgumentError on a mismatch.
|
|
37
|
+
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
|
|
38
|
+
# as keys, this will fail.
|
|
39
|
+
#
|
|
40
|
+
# ==== Examples
|
|
41
|
+
# { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
|
|
42
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
|
|
43
|
+
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
|
44
|
+
def assert_valid_keys(*valid_keys)
|
|
45
|
+
unknown_keys = keys - [valid_keys].flatten
|
|
46
|
+
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Giovanni
|
|
51
|
+
#
|
|
52
|
+
def assert_check_keys(*mkeys)
|
|
53
|
+
missing_keys = [mkeys].flatten - keys
|
|
54
|
+
raise(ArgumentError, "Missing key(s): #{missing_keys.join(", ")}") unless missing_keys.empty?
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class Hash #:nodoc:
|
|
61
|
+
include Sem4r::CoreExtensions::Hash
|
|
62
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# -------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
# -------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
module Sem4r
|
|
25
|
+
class GeoLocationService
|
|
26
|
+
include SoapCall
|
|
27
|
+
|
|
28
|
+
def initialize(connector)
|
|
29
|
+
@connector = connector
|
|
30
|
+
|
|
31
|
+
@header_namespace = "https://adwords.google.com/api/adwords/cm/v201003"
|
|
32
|
+
@service_namespace = @header_namespace
|
|
33
|
+
|
|
34
|
+
@sandbox_service_url = "https://adwords-sandbox.google.com/api/adwords/cm/v201003/GeoLocationService"
|
|
35
|
+
@production_service_url = "https://adwords.google.com/api/adwords/cm/v201003/GeoLocationService"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
soap_call_v2009 :get
|
|
39
|
+
|
|
40
|
+
################
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
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
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# -------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
# -------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
# <env:Body>
|
|
25
|
+
# <n3:get xmlns:n3="https://adwords.google.com/api/adwords/info/v200909">
|
|
26
|
+
# <n3:selector>
|
|
27
|
+
# <n3:dateRange xmlns:n4="https://adwords.google.com/api/adwords/cm/v200909">
|
|
28
|
+
# <n4:min>20090101</n4:min>
|
|
29
|
+
# <n4:max>20091030</n4:max>
|
|
30
|
+
# </n3:dateRange>
|
|
31
|
+
# <n3:apiUsageType>UNIT_COUNT</n3:apiUsageType>
|
|
32
|
+
# </n3:selector>
|
|
33
|
+
# </n3:get>
|
|
34
|
+
# </env:Body>
|
|
35
|
+
#</env:Envelope>
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
module Sem4r
|
|
39
|
+
class InfoService
|
|
40
|
+
include SoapCall
|
|
41
|
+
|
|
42
|
+
def initialize(connector)
|
|
43
|
+
@connector = connector
|
|
44
|
+
@header_namespace = "https://adwords.google.com/api/adwords/cm/v201003"
|
|
45
|
+
@service_namespace = "https://adwords.google.com/api/adwords/info/v201003"
|
|
46
|
+
|
|
47
|
+
@production_service_url = "https://adwords.google.com/api/adwords/info/v201003/InfoService"
|
|
48
|
+
@sandbox_service_url = "https://adwords-sandbox.google.com/api/adwords/info/v201003/InfoService"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
soap_call_v2009 :unit_cost
|
|
53
|
+
|
|
54
|
+
def _unit_cost( usage_type )
|
|
55
|
+
<<-EOFS
|
|
56
|
+
<s:get>
|
|
57
|
+
<s:selector>
|
|
58
|
+
<s:dateRange>
|
|
59
|
+
<min>20090101</min>
|
|
60
|
+
<max>20091105</max>
|
|
61
|
+
</s:dateRange>
|
|
62
|
+
<s:apiUsageType>#{usage_type}</s:apiUsageType>
|
|
63
|
+
</s:selector>
|
|
64
|
+
</s:get>
|
|
65
|
+
EOFS
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# Total units used since the beginning of the year: 0
|
|
70
|
+
# def old_unit_cost(credentials)
|
|
71
|
+
#
|
|
72
|
+
# soap_message = @connector.message_v2009(credentials, @header_namespace, @service_namespace )
|
|
73
|
+
# soap_message.body = "soap_body_content"
|
|
74
|
+
#
|
|
75
|
+
#
|
|
76
|
+
# soap_message.instance_eval do
|
|
77
|
+
# def build_soap_message
|
|
78
|
+
# str = <<-EOFS
|
|
79
|
+
#<?xml version="1.0" encoding="utf-8" ?>
|
|
80
|
+
# <env:Envelope
|
|
81
|
+
# xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
82
|
+
# xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
83
|
+
# xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
|
|
84
|
+
# xmlns="https://adwords.google.com/api/adwords/cm/v200909"
|
|
85
|
+
# xmlns:s="https://adwords.google.com/api/adwords/info/v200909">
|
|
86
|
+
# <env:Header>
|
|
87
|
+
# <s:RequestHeader env:mustUnderstand="0">
|
|
88
|
+
# <authToken>#{@credentials.authentication_token}</authToken>
|
|
89
|
+
# <userAgent>adwords4r: Sample User Agent</userAgent>
|
|
90
|
+
# <developerToken>#{@credentials.developer_token}</developerToken>
|
|
91
|
+
# </s:RequestHeader>
|
|
92
|
+
# </env:Header>
|
|
93
|
+
# <env:Body >
|
|
94
|
+
# <s:get>
|
|
95
|
+
# <s:selector>
|
|
96
|
+
# <s:dateRange>
|
|
97
|
+
# <min>20090101</min>
|
|
98
|
+
# <max>20091105</max>
|
|
99
|
+
# </s:dateRange>
|
|
100
|
+
# <s:apiUsageType>UNIT_COUNT</s:apiUsageType>
|
|
101
|
+
# </s:selector>
|
|
102
|
+
# </s:get>
|
|
103
|
+
# </env:Body>
|
|
104
|
+
# </env:Envelope>
|
|
105
|
+
#EOFS
|
|
106
|
+
# str
|
|
107
|
+
# end
|
|
108
|
+
# end
|
|
109
|
+
#
|
|
110
|
+
# result_xml = soap_message.send(@sandbox_service_url)
|
|
111
|
+
# result_xml
|
|
112
|
+
# end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#
|
|
23
|
+
# -------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
module Sem4r
|
|
26
|
+
|
|
27
|
+
class ReportDefinition < Base
|
|
28
|
+
|
|
29
|
+
attr_reader :id
|
|
30
|
+
|
|
31
|
+
g_accessor :name
|
|
32
|
+
|
|
33
|
+
def initialize(account, name = nil, &block)
|
|
34
|
+
super( account.adwords, account.credentials )
|
|
35
|
+
@account = account
|
|
36
|
+
self.name = name
|
|
37
|
+
if block_given?
|
|
38
|
+
@inside_initialize = true
|
|
39
|
+
block.arity < 1 ? instance_eval(&block) : block.call(self)
|
|
40
|
+
end
|
|
41
|
+
@inside_initialize = false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def inside_initialize?
|
|
45
|
+
@inside_initialize
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_s
|
|
49
|
+
"'#{@name}'"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def to_xml(tag)
|
|
53
|
+
builder = Builder::XmlMarkup.new
|
|
54
|
+
builder.tag!(tag) do |t|
|
|
55
|
+
t.reportName @name
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
###########################################################################
|
|
61
|
+
|
|
62
|
+
def self.from_element(account, el)
|
|
63
|
+
new(account) do
|
|
64
|
+
@id = el.elements["id"].text.strip.to_i
|
|
65
|
+
name el.elements["name"].text.strip
|
|
66
|
+
status el.elements['status'].text.strip # ACTIVE, PAUSED, DELETED
|
|
67
|
+
serving_status el.elements['servingStatus']
|
|
68
|
+
start_date el.elements['startDate']
|
|
69
|
+
end_date el.elements['endDate']
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.create(account, &block)
|
|
74
|
+
new(account, &block).save
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def save
|
|
78
|
+
unless @id
|
|
79
|
+
op = ReportDefinitionOperation.new
|
|
80
|
+
op.add(self)
|
|
81
|
+
puts op.to_xml "operations"
|
|
82
|
+
soap_message = service.report_definition.mutate(credentials, op.to_xml("operations"))
|
|
83
|
+
add_counters( soap_message.counters )
|
|
84
|
+
rval = REXML::XPath.first( soap_message.response, "//mutateResponse/rval")
|
|
85
|
+
id = REXML::XPath.match( rval, "value/id" ).first
|
|
86
|
+
@id = id.text.strip.to_i
|
|
87
|
+
end
|
|
88
|
+
self
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def delete
|
|
92
|
+
soap_message = service.campaign.delete(credentials, @id)
|
|
93
|
+
add_counters( soap_message.counters )
|
|
94
|
+
@id = -1 # logical delete
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
###########################################################################
|
|
98
|
+
|
|
99
|
+
def empty?
|
|
100
|
+
_ad_groups.empty?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
end
|