sem4r 0.1.3 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/Gemfile +2 -22
- data/Gemfile.lock +43 -20
- data/Rakefile +4 -2
- data/bin/sem +2 -6
- data/lib/sem4r/adwords.rb +8 -142
- data/lib/sem4r/campaign/campaign_account_extension.rb +4 -5
- data/lib/sem4r/profile.rb +173 -0
- data/lib/sem4r/sem4r_utilities.rb +113 -0
- data/lib/sem4r/v13_report/report.rb +5 -0
- data/lib/sem4r/version.rb +27 -0
- data/lib/sem4r.rb +5 -26
- data/lib/sem4r_cli/cli_sem.rb +116 -170
- data/lib/sem4r_cli/commands/{cli_ads.rb → cmd_ads.rb} +4 -4
- data/lib/sem4r_cli/commands/{cli_campaign.rb → cmd_campaign.rb} +7 -7
- data/lib/sem4r_cli/commands/{cli_clients.rb → cmd_clients.rb} +4 -5
- data/lib/sem4r_cli/commands/{cli_ideas.rb → cmd_ideas.rb} +7 -5
- data/lib/sem4r_cli/commands/{cli_info.rb → cmd_info.rb} +6 -6
- data/lib/sem4r_cli/commands/{cli_job.rb → cmd_job.rb} +4 -2
- data/lib/sem4r_cli/commands/{cli_keywords.rb → cmd_keywords.rb} +4 -4
- data/lib/sem4r_cli/commands/{cli_profile.rb → cmd_profile.rb} +23 -19
- data/lib/sem4r_cli/commands/{cli_repdef.rb → cmd_repdef.rb} +6 -4
- data/lib/sem4r_cli/commands/{cli_report.rb → cmd_report.rb} +8 -6
- data/lib/sem4r_cli.rb +6 -4
- data/lib/sem4r_debug_client/client.rb +200 -0
- data/lib/sem4r_debug_client.rb +31 -0
- data/lib/sem4r_sinatra/cli_server.rb +45 -0
- data/lib/sem4r_sinatra/helpers.rb +60 -0
- data/lib/sem4r_sinatra/web_server.rb +46 -0
- data/lib/sem4r_sinatra.rb +13 -0
- data/lib/sem4r_soap/http_connector.rb +5 -6
- data/lib/sem4r_soap/soap_dumper.rb +3 -14
- data/lib/sem4r_soap/soap_service.rb +5 -5
- data/lib/sem4r_soap/soap_service_v2010.rb +2 -2
- data/lib/sem4r_soap.rb +24 -0
- data/sem4r.gemspec +75 -313
- data/spec/fixtures/password.example.yml +5 -3
- data/spec/helpers/rspec_matchers.rb +2 -19
- data/spec/helpers/rspec_sem4r_helper.rb +25 -9
- data/spec/rspec_helper.rb +7 -0
- data/spec/sem4r/ad_group/ad_group_spec.rb +2 -3
- data/spec/sem4r/ad_group_ad/fixtures/mutate_add_mobile_ad-req.xml +8 -11
- data/spec/sem4r/ad_group_criterion/fixtures/mutate_add_negative_keyword-req.xml +1 -3
- data/spec/sem4r/adwords_spec.rb +0 -5
- data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-req.xml +18 -33
- data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-res.xml +232 -416
- data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-req.xml +55 -104
- data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-res.xml +25 -47
- data/spec/sem4r/geo_location/fixtures/get-req.xml +23 -40
- data/spec/sem4r/geo_location/fixtures/get-res.xml +31 -59
- data/spec/sem4r/info/fixtures/get-req.xml +19 -32
- data/spec/sem4r/info/fixtures/get-res.xml +16 -26
- data/spec/sem4r/profiles_spec.rb +52 -0
- data/spec/sem4r/report_definition/fixtures/get-list-repdef-req.xml +13 -20
- data/spec/sem4r/report_definition/fixtures/get-list-repdef-res.xml +34 -72
- data/spec/sem4r/report_definition/fixtures/getReportFields-req.xml +13 -22
- data/spec/sem4r/report_definition/fixtures/getReportFields-res.xml +476 -1198
- data/spec/sem4r/report_definition/fixtures/mutate-add-report-req.xml +30 -61
- data/spec/sem4r/report_definition/fixtures/mutate-add-report-res.xml +31 -67
- data/spec/sem4r/report_definition/report_definition_spec.rb +1 -1
- data/spec/sem4r/v13_report/fixtures/schedule_report_job-req.xml +11 -33
- data/spec/sem4r_cli/cli_spec.rb +4 -22
- data/tasks/sem4r.rake +0 -3
- data/tasks/yard.rake +2 -2
- metadata +188 -177
- data/VERSION.yml +0 -5
- data/lib/sem4r_cli/cli_helpers.rb +0 -59
- data/lib/sem4r_cli/cli_mini_framework.rb +0 -147
- data/tasks/jeweler.rake +0 -66
data/.gemtest
ADDED
File without changes
|
data/Gemfile
CHANGED
@@ -1,22 +1,2 @@
|
|
1
|
-
source
|
2
|
-
|
3
|
-
gem "builder"
|
4
|
-
gem "nokogiri"
|
5
|
-
gem "httpclient"
|
6
|
-
gem 'highline', :require => 'highline/import'
|
7
|
-
|
8
|
-
group :development do
|
9
|
-
gem "jeweler"
|
10
|
-
gem "rake"
|
11
|
-
gem "yard"
|
12
|
-
gem "bundler" # funny!
|
13
|
-
end
|
14
|
-
|
15
|
-
group :test do
|
16
|
-
gem "differ"
|
17
|
-
gem "rspec"
|
18
|
-
end
|
19
|
-
|
20
|
-
#platforms :jruby do
|
21
|
-
# gem 'jruby-openssl'
|
22
|
-
#end
|
1
|
+
source "http://rubygems.org"
|
2
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,42 +1,65 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sem4r (0.1.4)
|
5
|
+
builder
|
6
|
+
builder
|
7
|
+
haml
|
8
|
+
highline
|
9
|
+
httpclient
|
10
|
+
nokogiri
|
11
|
+
nokogiri
|
12
|
+
optparse-command (= 0.1.6)
|
13
|
+
signet
|
14
|
+
sinatra
|
15
|
+
|
1
16
|
GEM
|
2
17
|
remote: http://rubygems.org/
|
3
18
|
specs:
|
19
|
+
addressable (2.2.4)
|
4
20
|
builder (3.0.0)
|
5
21
|
diff-lcs (1.1.2)
|
6
|
-
differ (0.1.
|
7
|
-
|
22
|
+
differ (0.1.2)
|
23
|
+
haml (3.0.25)
|
8
24
|
highline (1.6.1)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
25
|
+
httpadapter (0.2.1)
|
26
|
+
addressable (~> 2.2.0)
|
27
|
+
httpclient (2.1.6.1)
|
28
|
+
json (1.5.1)
|
29
|
+
json (1.5.1-java)
|
14
30
|
nokogiri (1.4.4)
|
15
31
|
nokogiri (1.4.4-java)
|
16
32
|
weakling (>= 0.0.3)
|
33
|
+
optparse-command (0.1.6)
|
34
|
+
rack (1.2.1)
|
17
35
|
rake (0.8.7)
|
18
|
-
rspec (2.
|
19
|
-
rspec-core (~> 2.
|
20
|
-
rspec-expectations (~> 2.
|
21
|
-
rspec-mocks (~> 2.
|
22
|
-
rspec-core (2.
|
23
|
-
rspec-expectations (2.
|
36
|
+
rspec (2.5.0)
|
37
|
+
rspec-core (~> 2.5.0)
|
38
|
+
rspec-expectations (~> 2.5.0)
|
39
|
+
rspec-mocks (~> 2.5.0)
|
40
|
+
rspec-core (2.5.1)
|
41
|
+
rspec-expectations (2.5.0)
|
24
42
|
diff-lcs (~> 1.1.2)
|
25
|
-
rspec-mocks (2.
|
43
|
+
rspec-mocks (2.5.0)
|
44
|
+
signet (0.2.0)
|
45
|
+
addressable (~> 2.2.1)
|
46
|
+
httpadapter (~> 0.2.0)
|
47
|
+
json (~> 1.5.0)
|
48
|
+
sinatra (1.1.3)
|
49
|
+
rack (~> 1.1)
|
50
|
+
tilt (>= 1.2.2, < 2.0)
|
51
|
+
tilt (1.2.2)
|
26
52
|
weakling (0.0.4-java)
|
27
|
-
yard (0.6.
|
53
|
+
yard (0.6.4)
|
28
54
|
|
29
55
|
PLATFORMS
|
30
56
|
java
|
31
57
|
ruby
|
32
58
|
|
33
59
|
DEPENDENCIES
|
34
|
-
|
60
|
+
bundler
|
35
61
|
differ
|
36
|
-
highline
|
37
|
-
httpclient
|
38
|
-
jeweler
|
39
|
-
nokogiri
|
40
62
|
rake
|
41
63
|
rspec
|
64
|
+
sem4r!
|
42
65
|
yard
|
data/Rakefile
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
|
4
|
+
require 'bundler'
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
|
4
7
|
# Load tasks
|
5
8
|
Dir.glob('tasks/**/*.rake').each { |r| Rake.application.add_import r }
|
6
9
|
|
7
|
-
task :test => :
|
10
|
+
task :test => :spec
|
8
11
|
task :default => :spec
|
9
|
-
|
data/bin/sem
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
# -------------------------------------------------------------------------
|
4
4
|
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
@@ -21,15 +21,11 @@
|
|
21
21
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
22
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
23
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
-
#
|
25
24
|
# -------------------------------------------------------------------------
|
26
25
|
|
27
26
|
require 'rubygems'
|
28
|
-
|
29
27
|
cwd = File.expand_path( File.join( File.dirname(__FILE__), "..", "lib" ) )
|
30
28
|
$:.unshift(cwd) unless $:.include?(cwd)
|
31
29
|
require 'sem4r_cli'
|
32
30
|
|
33
|
-
|
34
|
-
include Sem4rCli
|
35
|
-
exit CliSem.run
|
31
|
+
Sem4rCli::CliSem.run!
|
data/lib/sem4r/adwords.rb
CHANGED
@@ -22,7 +22,6 @@
|
|
22
22
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
23
|
# -------------------------------------------------------------------
|
24
24
|
|
25
|
-
|
26
25
|
module Sem4r
|
27
26
|
class Adwords
|
28
27
|
|
@@ -46,78 +45,6 @@ module Sem4r
|
|
46
45
|
new("production", options)
|
47
46
|
end
|
48
47
|
|
49
|
-
#
|
50
|
-
# @private
|
51
|
-
# Search configuration file in standard locations
|
52
|
-
# @return [OpenStruct] with
|
53
|
-
# :config_dir
|
54
|
-
# :config_file
|
55
|
-
# :password_file
|
56
|
-
#
|
57
|
-
def search_config
|
58
|
-
config_filename = "sem4r.yml"
|
59
|
-
password_filename = "sem4r_passwords.yml"
|
60
|
-
|
61
|
-
#
|
62
|
-
# try current directory
|
63
|
-
#
|
64
|
-
# return File.expand_path(config_filename) if File.exists?( config_filename)
|
65
|
-
|
66
|
-
#
|
67
|
-
# try ~/.sem4r/sem4r.yml
|
68
|
-
#
|
69
|
-
# require 'etc'
|
70
|
-
# homedir = Etc.getpwuid.dir
|
71
|
-
homedir = ENV['HOME']
|
72
|
-
config_filepath = File.join(homedir, ".sem4r", config_filename)
|
73
|
-
if File.exists?(config_filepath)
|
74
|
-
return OpenStruct.new(
|
75
|
-
:config_dir => File.join(homedir, ".sem4r"),
|
76
|
-
:config_file => config_filepath,
|
77
|
-
:password_file => File.join(homedir, ".sem4r", password_filename))
|
78
|
-
end
|
79
|
-
|
80
|
-
#
|
81
|
-
# try <home_sem4r>/config/sem4r
|
82
|
-
#
|
83
|
-
config_filepath = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "config", config_filename))
|
84
|
-
if File.exists?(config_filepath)
|
85
|
-
return OpenStruct.new(
|
86
|
-
:config_dir => nil,
|
87
|
-
:config_file => config_filepath,
|
88
|
-
:password_file => nil)
|
89
|
-
end
|
90
|
-
|
91
|
-
config_filepath = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "config", "sem4r.example.yml"))
|
92
|
-
if File.exists?(config_filepath)
|
93
|
-
return OpenStruct.new(
|
94
|
-
:config_dir => nil,
|
95
|
-
:config_file => config_filepath,
|
96
|
-
:password_file => nil)
|
97
|
-
end
|
98
|
-
|
99
|
-
OpenStruct.new(
|
100
|
-
:config_dir => nil,
|
101
|
-
:config_file => nil,
|
102
|
-
:password_file => nil)
|
103
|
-
end
|
104
|
-
|
105
|
-
#
|
106
|
-
# Return list of profile contained into config file
|
107
|
-
#
|
108
|
-
def profiles(profile_file = nil)
|
109
|
-
unless profile_file
|
110
|
-
config = search_config
|
111
|
-
unless config
|
112
|
-
raise Sem4rError, "config file 'sem4r' not found"
|
113
|
-
end
|
114
|
-
profile_file = config.config_file
|
115
|
-
end
|
116
|
-
# puts "Loaded profiles from #{profile_file}"
|
117
|
-
yaml = YAML::load(File.open(profile_file))
|
118
|
-
profiles = yaml['google_adwords']
|
119
|
-
profiles
|
120
|
-
end
|
121
48
|
end
|
122
49
|
|
123
50
|
#
|
@@ -154,23 +81,23 @@ module Sem4r
|
|
154
81
|
|
155
82
|
config_file = options.delete("config_file")
|
156
83
|
password_file = options.delete("password_file")
|
157
|
-
configure(config_file, password_file)
|
84
|
+
@config = Profile.configure(config_file, password_file)
|
158
85
|
|
159
86
|
@profile = profile.to_s
|
160
|
-
@options = load_config(@profile)
|
87
|
+
@options = Profile.load_config(@config, @profile)
|
161
88
|
@options = @options.merge(options)
|
162
89
|
elsif profile.respond_to?(:keys)
|
163
90
|
# new( {:environment=>"...", email => "..." } )
|
164
91
|
options = profile.stringify_keys
|
165
92
|
options.assert_valid_keys( *(all_keys-%w{config_file password_file}) )
|
166
|
-
configure
|
93
|
+
@config = Profile.configure
|
167
94
|
@options = options
|
168
95
|
@profile = "anonymous_" + @options["environment"]
|
169
96
|
else
|
170
97
|
# new( "sandbox" )
|
171
98
|
@profile = profile.to_s
|
172
|
-
configure
|
173
|
-
@options = load_config(@profile)
|
99
|
+
@config = Profile.configure
|
100
|
+
@options = Profile.load_config(@config, @profile)
|
174
101
|
end
|
175
102
|
if ["sandbox", "production"].include?(profile)
|
176
103
|
if @options["environment"].nil?
|
@@ -181,7 +108,7 @@ module Sem4r
|
|
181
108
|
end
|
182
109
|
end
|
183
110
|
|
184
|
-
|
111
|
+
Profile.try_to_find_in_password_file("password", @options, @config) unless @options["password"]
|
185
112
|
end
|
186
113
|
|
187
114
|
def to_s
|
@@ -192,7 +119,7 @@ module Sem4r
|
|
192
119
|
# returns profiles contained into current config file
|
193
120
|
#
|
194
121
|
def profiles
|
195
|
-
|
122
|
+
Profile.profiles @config.config_file
|
196
123
|
end
|
197
124
|
|
198
125
|
#
|
@@ -200,7 +127,7 @@ module Sem4r
|
|
200
127
|
#
|
201
128
|
def config_file
|
202
129
|
return @config.config_file if @config
|
203
|
-
@config =
|
130
|
+
@config = Profile.search_config
|
204
131
|
unless @config
|
205
132
|
puts "cannot find configuration files"
|
206
133
|
end
|
@@ -227,67 +154,6 @@ module Sem4r
|
|
227
154
|
@options["password"]=pwd
|
228
155
|
end
|
229
156
|
|
230
|
-
def try_to_find_password_in_password_file
|
231
|
-
return unless @config.password_file
|
232
|
-
return unless File.exists?(@config.password_file)
|
233
|
-
passwords = YAML.load(File.open(@config.password_file))
|
234
|
-
pass = passwords[@options["email"]]
|
235
|
-
@options["password"] = pass if pass
|
236
|
-
end
|
237
|
-
|
238
|
-
def save_passwords
|
239
|
-
if @config.password_file.nil?
|
240
|
-
raise "cannot save password"
|
241
|
-
end
|
242
|
-
puts "save password in #{@config.password_file} (security warning!)"
|
243
|
-
passwords = {}
|
244
|
-
if File.exists?(@config.password_file)
|
245
|
-
passwords = YAML.load(File.open(@config.password_file))
|
246
|
-
end
|
247
|
-
passwords[@options["email"]] = @options["password"]
|
248
|
-
File.open(@config.password_file, "w") do |f|
|
249
|
-
f.write(passwords.to_yaml)
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
private
|
254
|
-
|
255
|
-
#
|
256
|
-
# @private
|
257
|
-
#
|
258
|
-
# force config paths
|
259
|
-
# and the config file
|
260
|
-
#
|
261
|
-
def configure(config_file = nil, password_file = nil)
|
262
|
-
@config = Adwords.search_config
|
263
|
-
unless config_file.nil?
|
264
|
-
config_file = File.expand_path(config_file)
|
265
|
-
unless File.exists?(config_file)
|
266
|
-
raise "#{config_file} not exists"
|
267
|
-
end
|
268
|
-
@config.config_file = config_file
|
269
|
-
end
|
270
|
-
unless password_file.nil?
|
271
|
-
password_file = File.expand_path(password_file)
|
272
|
-
@config.password_file = password_file
|
273
|
-
end
|
274
|
-
@config
|
275
|
-
end
|
276
|
-
|
277
|
-
|
278
|
-
# @private
|
279
|
-
# load the configuration
|
280
|
-
def load_config(profile)
|
281
|
-
unless @config.config_file
|
282
|
-
raise Sem4rError, "config file 'sem4r' not found"
|
283
|
-
end
|
284
|
-
# puts "Loaded profiles from #{config_file}"
|
285
|
-
yaml = YAML::load(File.open(@config.config_file))
|
286
|
-
config = yaml['google_adwords'][profile]
|
287
|
-
config || {}
|
288
|
-
end
|
289
|
-
|
290
|
-
public
|
291
157
|
|
292
158
|
##########################################################################
|
293
159
|
# logging
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
# -------------------------------------------------------------------------
|
3
3
|
# Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining
|
6
6
|
# a copy of this software and associated documentation files (the
|
7
7
|
# "Software"), to deal in the Software without restriction, including
|
@@ -9,10 +9,10 @@
|
|
9
9
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
10
|
# permit persons to whom the Software is furnished to do so, subject to
|
11
11
|
# the following conditions:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# The above copyright notice and this permission notice shall be
|
14
14
|
# included in all copies or substantial portions of the Software.
|
15
|
-
#
|
15
|
+
#
|
16
16
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
17
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
18
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -20,7 +20,6 @@
|
|
20
20
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
22
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
-
#
|
24
23
|
# -------------------------------------------------------------------------
|
25
24
|
|
26
25
|
module Sem4r
|
@@ -85,4 +84,4 @@ module Sem4r
|
|
85
84
|
include AccountCampaignExtension
|
86
85
|
end
|
87
86
|
|
88
|
-
end
|
87
|
+
end
|
@@ -0,0 +1,173 @@
|
|
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 Profile
|
28
|
+
|
29
|
+
attr_reader :profile
|
30
|
+
|
31
|
+
class << self
|
32
|
+
|
33
|
+
#
|
34
|
+
# @private
|
35
|
+
# Search configuration file in standard locations
|
36
|
+
# @return [OpenStruct] with
|
37
|
+
# :config_dir
|
38
|
+
# :config_file
|
39
|
+
# :password_file
|
40
|
+
#
|
41
|
+
def search_config
|
42
|
+
config_filename = "sem4r.yml"
|
43
|
+
password_filename = "sem4r_passwords.yml"
|
44
|
+
|
45
|
+
#
|
46
|
+
# try current directory
|
47
|
+
#
|
48
|
+
# return File.expand_path(config_filename) if File.exists?( config_filename)
|
49
|
+
|
50
|
+
#
|
51
|
+
# try ~/.sem4r/sem4r.yml
|
52
|
+
#
|
53
|
+
# require 'etc'
|
54
|
+
# homedir = Etc.getpwuid.dir
|
55
|
+
homedir = ENV['HOME']
|
56
|
+
config_filepath = File.join(homedir, ".sem4r", config_filename)
|
57
|
+
if File.exists?(config_filepath)
|
58
|
+
return OpenStruct.new(
|
59
|
+
:config_dir => File.join(homedir, ".sem4r"),
|
60
|
+
:config_file => config_filepath,
|
61
|
+
:password_file => File.join(homedir, ".sem4r", password_filename))
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# try <home_sem4r>/config/sem4r
|
66
|
+
#
|
67
|
+
config_filepath = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "config", config_filename))
|
68
|
+
if File.exists?(config_filepath)
|
69
|
+
return OpenStruct.new(
|
70
|
+
:config_dir => nil,
|
71
|
+
:config_file => config_filepath,
|
72
|
+
:password_file => nil)
|
73
|
+
end
|
74
|
+
|
75
|
+
config_filepath = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "config", "sem4r.example.yml"))
|
76
|
+
if File.exists?(config_filepath)
|
77
|
+
return OpenStruct.new(
|
78
|
+
:config_dir => nil,
|
79
|
+
:config_file => config_filepath,
|
80
|
+
:password_file => nil)
|
81
|
+
end
|
82
|
+
|
83
|
+
OpenStruct.new(
|
84
|
+
:config_dir => nil,
|
85
|
+
:config_file => nil,
|
86
|
+
:password_file => nil)
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Return list of profile contained into config file
|
91
|
+
#
|
92
|
+
def profiles(profile_file = nil)
|
93
|
+
unless profile_file
|
94
|
+
config = search_config
|
95
|
+
unless config
|
96
|
+
raise Sem4rError, "config file 'sem4r' not found"
|
97
|
+
end
|
98
|
+
profile_file = config.config_file
|
99
|
+
end
|
100
|
+
# puts "Loaded profiles from #{profile_file}"
|
101
|
+
yaml = YAML::load(File.open(profile_file))
|
102
|
+
profiles = yaml['google_adwords']
|
103
|
+
profiles
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# @private
|
108
|
+
#
|
109
|
+
# force config paths
|
110
|
+
# and the config file
|
111
|
+
#
|
112
|
+
def configure(config_file = nil, password_file = nil)
|
113
|
+
config = Profile.search_config
|
114
|
+
unless config_file.nil?
|
115
|
+
config_file = File.expand_path(config_file)
|
116
|
+
unless File.exists?(config_file)
|
117
|
+
raise "#{config_file} not exists"
|
118
|
+
end
|
119
|
+
config.config_file = config_file
|
120
|
+
end
|
121
|
+
unless password_file.nil?
|
122
|
+
password_file = File.expand_path(password_file)
|
123
|
+
config.password_file = password_file
|
124
|
+
end
|
125
|
+
config
|
126
|
+
end
|
127
|
+
|
128
|
+
# @private
|
129
|
+
# load the configuration
|
130
|
+
def load_config(config, profile)
|
131
|
+
unless config.config_file
|
132
|
+
raise Sem4rError, "config file 'sem4r' not found"
|
133
|
+
end
|
134
|
+
# puts "Loaded profiles from #{config_file}"
|
135
|
+
yaml = YAML::load(File.open(config.config_file))
|
136
|
+
config = yaml['google_adwords'][profile.to_s]
|
137
|
+
config || {}
|
138
|
+
end
|
139
|
+
|
140
|
+
def try_to_find_in_password_file(key, options, config)
|
141
|
+
return unless config.password_file
|
142
|
+
return unless File.exists?(config.password_file)
|
143
|
+
passwords = YAML.load(File.open(config.password_file))
|
144
|
+
t = passwords[options["email"]]
|
145
|
+
if t and t[key]
|
146
|
+
options[key] = t[key]
|
147
|
+
else
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def save_passwords(key, options, config)
|
153
|
+
if config.password_file.nil?
|
154
|
+
raise "no password file defined"
|
155
|
+
end
|
156
|
+
# TODO: check permission password file
|
157
|
+
puts "save password in #{config.password_file} (security warning!)"
|
158
|
+
passwords = {}
|
159
|
+
if File.exists?(config.password_file)
|
160
|
+
passwords = YAML.load(File.open(config.password_file))
|
161
|
+
end
|
162
|
+
passwords[options["email"]] ||= {}
|
163
|
+
passwords[options["email"]][key] = options[key]
|
164
|
+
File.open(config.password_file, "w") do |f|
|
165
|
+
f.write(passwords.to_yaml)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end # module Sem4r
|
@@ -0,0 +1,113 @@
|
|
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
|
+
#def pretty_xml(xml)
|
28
|
+
# normalized = Class.new(REXML::Formatters::Pretty) do
|
29
|
+
# def write_text(node, output)
|
30
|
+
# super(node.to_s.strip, output)
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# normalized.new(0, false).write(xml, xml_pretty='')
|
34
|
+
# xml_pretty
|
35
|
+
#end
|
36
|
+
|
37
|
+
def self.pretty_print_xml_with_rexml(xml)
|
38
|
+
# TODO: using nokogiri also for pretty print xml ?
|
39
|
+
require 'rexml/document'
|
40
|
+
begin
|
41
|
+
xml_document = REXML::Document.new(xml)
|
42
|
+
f = REXML::Formatters::Pretty.new
|
43
|
+
out = String.new
|
44
|
+
f.write(xml_document, out)
|
45
|
+
# remove xml directive
|
46
|
+
out.gsub("<?xml version.rb='1.0' encoding='UTF-8'?>", "")
|
47
|
+
rescue
|
48
|
+
# rescue RuntimeError
|
49
|
+
puts "----------------------------------"
|
50
|
+
puts xml
|
51
|
+
puts "----------------------------------"
|
52
|
+
raise
|
53
|
+
end
|
54
|
+
out
|
55
|
+
end
|
56
|
+
|
57
|
+
@_nokogiri_xsl =<<-EOFS
|
58
|
+
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
59
|
+
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes"/>
|
60
|
+
<xsl:param name="indent-increment" select="' '"/>
|
61
|
+
|
62
|
+
<xsl:template name="newline">
|
63
|
+
<xsl:text disable-output-escaping="yes">
|
64
|
+
</xsl:text>
|
65
|
+
</xsl:template>
|
66
|
+
|
67
|
+
<xsl:template match="comment() | processing-instruction()">
|
68
|
+
<xsl:param name="indent" select="''"/>
|
69
|
+
<xsl:call-template name="newline"/>
|
70
|
+
<xsl:value-of select="$indent"/>
|
71
|
+
<xsl:copy />
|
72
|
+
</xsl:template>
|
73
|
+
|
74
|
+
<xsl:template match="text()">
|
75
|
+
<xsl:param name="indent" select="''"/>
|
76
|
+
<xsl:call-template name="newline"/>
|
77
|
+
<xsl:value-of select="$indent"/>
|
78
|
+
<xsl:value-of select="normalize-space(.)"/>
|
79
|
+
</xsl:template>
|
80
|
+
|
81
|
+
<xsl:template match="text()[normalize-space(.)='']"/>
|
82
|
+
|
83
|
+
<xsl:template match="*">
|
84
|
+
<xsl:param name="indent" select="''"/>
|
85
|
+
<xsl:call-template name="newline"/>
|
86
|
+
<xsl:value-of select="$indent"/>
|
87
|
+
<xsl:choose>
|
88
|
+
<xsl:when test="count(child::*) > 0">
|
89
|
+
<xsl:copy>
|
90
|
+
<xsl:copy-of select="@*"/>
|
91
|
+
<xsl:apply-templates select="*|text()">
|
92
|
+
<xsl:with-param name="indent" select="concat ($indent, $indent-increment)"/>
|
93
|
+
</xsl:apply-templates>
|
94
|
+
<xsl:call-template name="newline"/>
|
95
|
+
<xsl:value-of select="$indent"/>
|
96
|
+
</xsl:copy>
|
97
|
+
</xsl:when>
|
98
|
+
<xsl:otherwise>
|
99
|
+
<xsl:copy-of select="."/>
|
100
|
+
</xsl:otherwise>
|
101
|
+
</xsl:choose>
|
102
|
+
</xsl:template>
|
103
|
+
</xsl:stylesheet>
|
104
|
+
EOFS
|
105
|
+
|
106
|
+
def self.pretty_print_xml_with_nokogiri(xml)
|
107
|
+
doc = Nokogiri::XML(xml)
|
108
|
+
xslt = Nokogiri::XSLT(@_nokogiri_xsl)
|
109
|
+
out = xslt.transform(doc).root.to_xml # using root omit the xml declaration
|
110
|
+
# out.gsub(/<\?xml version.rb=('|")1.0('|") encoding=('|")UTF-8('|")\?>/, "")
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|