sem4r 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. data/.gemtest +0 -0
  2. data/Gemfile +2 -22
  3. data/Gemfile.lock +43 -20
  4. data/Rakefile +4 -2
  5. data/bin/sem +2 -6
  6. data/lib/sem4r/adwords.rb +8 -142
  7. data/lib/sem4r/campaign/campaign_account_extension.rb +4 -5
  8. data/lib/sem4r/profile.rb +173 -0
  9. data/lib/sem4r/sem4r_utilities.rb +113 -0
  10. data/lib/sem4r/v13_report/report.rb +5 -0
  11. data/lib/sem4r/version.rb +27 -0
  12. data/lib/sem4r.rb +5 -26
  13. data/lib/sem4r_cli/cli_sem.rb +116 -170
  14. data/lib/sem4r_cli/commands/{cli_ads.rb → cmd_ads.rb} +4 -4
  15. data/lib/sem4r_cli/commands/{cli_campaign.rb → cmd_campaign.rb} +7 -7
  16. data/lib/sem4r_cli/commands/{cli_clients.rb → cmd_clients.rb} +4 -5
  17. data/lib/sem4r_cli/commands/{cli_ideas.rb → cmd_ideas.rb} +7 -5
  18. data/lib/sem4r_cli/commands/{cli_info.rb → cmd_info.rb} +6 -6
  19. data/lib/sem4r_cli/commands/{cli_job.rb → cmd_job.rb} +4 -2
  20. data/lib/sem4r_cli/commands/{cli_keywords.rb → cmd_keywords.rb} +4 -4
  21. data/lib/sem4r_cli/commands/{cli_profile.rb → cmd_profile.rb} +23 -19
  22. data/lib/sem4r_cli/commands/{cli_repdef.rb → cmd_repdef.rb} +6 -4
  23. data/lib/sem4r_cli/commands/{cli_report.rb → cmd_report.rb} +8 -6
  24. data/lib/sem4r_cli.rb +6 -4
  25. data/lib/sem4r_debug_client/client.rb +200 -0
  26. data/lib/sem4r_debug_client.rb +31 -0
  27. data/lib/sem4r_sinatra/cli_server.rb +45 -0
  28. data/lib/sem4r_sinatra/helpers.rb +60 -0
  29. data/lib/sem4r_sinatra/web_server.rb +46 -0
  30. data/lib/sem4r_sinatra.rb +13 -0
  31. data/lib/sem4r_soap/http_connector.rb +5 -6
  32. data/lib/sem4r_soap/soap_dumper.rb +3 -14
  33. data/lib/sem4r_soap/soap_service.rb +5 -5
  34. data/lib/sem4r_soap/soap_service_v2010.rb +2 -2
  35. data/lib/sem4r_soap.rb +24 -0
  36. data/sem4r.gemspec +75 -313
  37. data/spec/fixtures/password.example.yml +5 -3
  38. data/spec/helpers/rspec_matchers.rb +2 -19
  39. data/spec/helpers/rspec_sem4r_helper.rb +25 -9
  40. data/spec/rspec_helper.rb +7 -0
  41. data/spec/sem4r/ad_group/ad_group_spec.rb +2 -3
  42. data/spec/sem4r/ad_group_ad/fixtures/mutate_add_mobile_ad-req.xml +8 -11
  43. data/spec/sem4r/ad_group_criterion/fixtures/mutate_add_negative_keyword-req.xml +1 -3
  44. data/spec/sem4r/adwords_spec.rb +0 -5
  45. data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-req.xml +18 -33
  46. data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-res.xml +232 -416
  47. data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-req.xml +55 -104
  48. data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-res.xml +25 -47
  49. data/spec/sem4r/geo_location/fixtures/get-req.xml +23 -40
  50. data/spec/sem4r/geo_location/fixtures/get-res.xml +31 -59
  51. data/spec/sem4r/info/fixtures/get-req.xml +19 -32
  52. data/spec/sem4r/info/fixtures/get-res.xml +16 -26
  53. data/spec/sem4r/profiles_spec.rb +52 -0
  54. data/spec/sem4r/report_definition/fixtures/get-list-repdef-req.xml +13 -20
  55. data/spec/sem4r/report_definition/fixtures/get-list-repdef-res.xml +34 -72
  56. data/spec/sem4r/report_definition/fixtures/getReportFields-req.xml +13 -22
  57. data/spec/sem4r/report_definition/fixtures/getReportFields-res.xml +476 -1198
  58. data/spec/sem4r/report_definition/fixtures/mutate-add-report-req.xml +30 -61
  59. data/spec/sem4r/report_definition/fixtures/mutate-add-report-res.xml +31 -67
  60. data/spec/sem4r/report_definition/report_definition_spec.rb +1 -1
  61. data/spec/sem4r/v13_report/fixtures/schedule_report_job-req.xml +11 -33
  62. data/spec/sem4r_cli/cli_spec.rb +4 -22
  63. data/tasks/sem4r.rake +0 -3
  64. data/tasks/yard.rake +2 -2
  65. metadata +188 -177
  66. data/VERSION.yml +0 -5
  67. data/lib/sem4r_cli/cli_helpers.rb +0 -59
  68. data/lib/sem4r_cli/cli_mini_framework.rb +0 -147
  69. data/tasks/jeweler.rake +0 -66
data/.gemtest ADDED
File without changes
data/Gemfile CHANGED
@@ -1,22 +1,2 @@
1
- source :gemcutter
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.1)
7
- git (1.2.5)
22
+ differ (0.1.2)
23
+ haml (3.0.25)
8
24
  highline (1.6.1)
9
- httpclient (2.1.5.2)
10
- jeweler (1.5.1)
11
- bundler (~> 1.0.0)
12
- git (>= 1.2.5)
13
- rake
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.2.0)
19
- rspec-core (~> 2.2)
20
- rspec-expectations (~> 2.2)
21
- rspec-mocks (~> 2.2)
22
- rspec-core (2.2.1)
23
- rspec-expectations (2.2.0)
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.2.0)
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.3)
53
+ yard (0.6.4)
28
54
 
29
55
  PLATFORMS
30
56
  java
31
57
  ruby
32
58
 
33
59
  DEPENDENCIES
34
- builder
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 => :check_dependencies
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
- include Sem4r
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
- try_to_find_password_in_password_file unless @options["password"]
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
- self.class.profiles @config.config_file
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 = Adwords.search_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