sem4r 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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