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.
- 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
@@ -27,27 +27,30 @@ module Sem4rCli
|
|
27
27
|
#
|
28
28
|
# Manage Sem4r profiles
|
29
29
|
#
|
30
|
-
class
|
30
|
+
class CommandProfile < OptParseCommand::Command
|
31
|
+
|
32
|
+
CliSem.register_command(self)
|
31
33
|
|
32
34
|
def self.command
|
33
35
|
"profile"
|
34
36
|
end
|
35
37
|
|
36
|
-
def self.
|
37
|
-
|
38
|
+
def self.description
|
39
|
+
"manage sem4r profiles (subcommands: #{sub_commands.join(', ')})"
|
38
40
|
end
|
39
41
|
|
40
|
-
def self.
|
41
|
-
"
|
42
|
+
def self.usage
|
43
|
+
"usage profile"
|
42
44
|
end
|
43
45
|
|
44
|
-
def
|
45
|
-
|
46
|
+
def self.sub_commands
|
47
|
+
%w{list create}
|
46
48
|
end
|
47
49
|
|
48
|
-
|
50
|
+
|
51
|
+
def option_parser(options)
|
49
52
|
opt_parser = OptionParser.new
|
50
|
-
opt_parser.banner = "Usage #{self.class.command} [command_options] [#{self.class.
|
53
|
+
opt_parser.banner = "Usage #{self.class.command} [command_options] [#{self.class.sub_commands.join("|")}]"
|
51
54
|
opt_parser.separator ""
|
52
55
|
opt_parser.separator "#{self.class.description}"
|
53
56
|
opt_parser.on("-h", "--help", "show this message") do
|
@@ -56,20 +59,21 @@ module Sem4rCli
|
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
59
|
-
def
|
62
|
+
def exec(sem4r_cli, options, rest)
|
60
63
|
options = OpenStruct.new
|
61
|
-
rest = command_opt_parser(options).parse(
|
64
|
+
rest = command_opt_parser(options).parse(rest)
|
62
65
|
return false if options.exit
|
63
66
|
if rest.empty?
|
64
|
-
puts "missing command"
|
65
|
-
return false
|
67
|
+
# puts "missing command"
|
68
|
+
# return false
|
69
|
+
rest << "list" # default command
|
66
70
|
end
|
67
71
|
|
68
72
|
ret = true
|
69
|
-
|
70
|
-
|
71
|
-
adwords =
|
72
|
-
case
|
73
|
+
sub_command = rest[0]
|
74
|
+
sub_command_args = rest[1..-1]
|
75
|
+
adwords = sem4r_cli.adwords
|
76
|
+
case sub_command
|
73
77
|
when "list"
|
74
78
|
puts "Profiles:"
|
75
79
|
|
@@ -84,12 +88,12 @@ module Sem4rCli
|
|
84
88
|
o.environment = profiles[s]['environment']
|
85
89
|
items << o
|
86
90
|
end
|
87
|
-
|
91
|
+
OptParseCommand::report(items, :name, :environment, :email, :mutable)
|
88
92
|
when "create"
|
89
93
|
puts "Tobe done :-)"
|
90
94
|
|
91
95
|
else
|
92
|
-
puts "unknow
|
96
|
+
puts "unknow command '#{sub_command}'; must be one of #{self.class.sub_commands.join(", ")}"
|
93
97
|
return false
|
94
98
|
end
|
95
99
|
ret
|
@@ -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
|
@@ -27,7 +27,9 @@ module Sem4rCli
|
|
27
27
|
#
|
28
28
|
# Report Definition (v201008 api)
|
29
29
|
#
|
30
|
-
class
|
30
|
+
class CommandRepDef < OptParseCommand::Command
|
31
|
+
|
32
|
+
CliSem.register_command(CliSem)
|
31
33
|
|
32
34
|
def self.command
|
33
35
|
"repdef"
|
@@ -27,7 +27,9 @@ module Sem4rCli
|
|
27
27
|
#
|
28
28
|
# report (v13 api)
|
29
29
|
#
|
30
|
-
class
|
30
|
+
class CommandReport < OptParseCommand::Command
|
31
|
+
|
32
|
+
CliSem.register_command(self)
|
31
33
|
|
32
34
|
def self.command
|
33
35
|
"report"
|
@@ -39,7 +41,7 @@ module Sem4rCli
|
|
39
41
|
|
40
42
|
def initialize(common_args)
|
41
43
|
@common_args = common_args
|
42
|
-
@
|
44
|
+
@subcommands = %w{list download schedule}
|
43
45
|
end
|
44
46
|
|
45
47
|
def parse_and_run(argv)
|
@@ -64,7 +66,7 @@ module Sem4rCli
|
|
64
66
|
|
65
67
|
when "schedule"
|
66
68
|
ret = schedule(subcommand_args)
|
67
|
-
|
69
|
+
|
68
70
|
else
|
69
71
|
puts "unknow subcommand '#{subcommand}'; must be one of #{@subcomands.join(", ")}"
|
70
72
|
return false
|
@@ -78,7 +80,7 @@ module Sem4rCli
|
|
78
80
|
|
79
81
|
def command_opt_parser(options)
|
80
82
|
opt_parser = OptionParser.new
|
81
|
-
opt_parser.banner = "Usage #{self.class.command} [command_options ] [#{@
|
83
|
+
opt_parser.banner = "Usage #{self.class.command} [command_options ] [#{@subcommands.join("|")}]"
|
82
84
|
opt_parser.separator ""
|
83
85
|
opt_parser.separator "#{self.class.description}"
|
84
86
|
|
@@ -93,7 +95,7 @@ module Sem4rCli
|
|
93
95
|
#
|
94
96
|
def download(args)
|
95
97
|
if args.length != 1
|
96
|
-
puts "missing report id for '
|
98
|
+
puts "missing report id for 'download' subcommand"
|
97
99
|
return false
|
98
100
|
end
|
99
101
|
|
@@ -105,7 +107,7 @@ module Sem4rCli
|
|
105
107
|
end
|
106
108
|
|
107
109
|
if report.status != 'Completed'
|
108
|
-
puts "cannot
|
110
|
+
puts "cannot download report with status '#{report.status}'"
|
109
111
|
return false
|
110
112
|
end
|
111
113
|
|
data/lib/sem4r_cli.rb
CHANGED
@@ -22,15 +22,17 @@
|
|
22
22
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
23
|
# -------------------------------------------------------------------
|
24
24
|
|
25
|
-
|
25
|
+
#
|
26
|
+
# rubygems
|
27
|
+
#
|
26
28
|
require "highline/import" # to ask password on command line
|
29
|
+
gem "optparse-command", "0.1.6"
|
30
|
+
require 'optparse-command'
|
27
31
|
|
28
32
|
require 'sem4r'
|
29
|
-
require 'sem4r_cli/cli_mini_framework'
|
30
33
|
require 'sem4r_cli/cli_sem'
|
31
|
-
require 'sem4r_cli/cli_helpers'
|
32
34
|
|
33
35
|
# commands
|
34
|
-
Dir[File.join( File.dirname(__FILE__), "sem4r_cli", "commands", "*.rb" )].each do |f|
|
36
|
+
Dir[File.join( File.dirname(__FILE__), "sem4r_cli", "commands", "cmd*.rb" )].each do |f|
|
35
37
|
require f
|
36
38
|
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class VarForErb
|
3
|
+
|
4
|
+
attr_accessor :email
|
5
|
+
attr_accessor :password
|
6
|
+
attr_accessor :auth_token
|
7
|
+
attr_accessor :developer_token
|
8
|
+
attr_accessor :client_email
|
9
|
+
|
10
|
+
def get_binding
|
11
|
+
binding
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Client
|
16
|
+
|
17
|
+
def initialize(profile = :sandbox)
|
18
|
+
|
19
|
+
@config = Sem4r::Profile.configure
|
20
|
+
@options = Sem4r::Profile.load_config(@config, profile)
|
21
|
+
|
22
|
+
Sem4r::Profile.try_to_find_in_password_file("password", @options, @config)
|
23
|
+
Sem4r::Profile.try_to_find_in_password_file("auth_token", @options, @config)
|
24
|
+
|
25
|
+
Sem4r::Profile.try_to_find_in_password_file("token_credential_key", @options, @config)
|
26
|
+
Sem4r::Profile.try_to_find_in_password_file("token_credential_secret", @options, @config)
|
27
|
+
|
28
|
+
@email = @options["email"]
|
29
|
+
@password = @options["password"]
|
30
|
+
@auth_token = @options["auth_token"]
|
31
|
+
|
32
|
+
@token_credential_key = @options["token_credential_key"]
|
33
|
+
@token_credential_secret = @options["token_credential_secret"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def send(service_url, soap_action, filename)
|
37
|
+
puts "** #{service_url}"
|
38
|
+
|
39
|
+
request_xml = read_message(filename)
|
40
|
+
puts Sem4r::pretty_print_xml_with_nokogiri(request_xml)
|
41
|
+
|
42
|
+
headers = {
|
43
|
+
"Content-Type" => "text/xml; charset=utf-8",
|
44
|
+
"Content-Length" => request_xml.length.to_s,
|
45
|
+
"SOAPAction" => soap_action}
|
46
|
+
client = HTTPClient.new(:agent_name => 'Ruby')
|
47
|
+
response = client.post(service_url, request_xml, headers)
|
48
|
+
# pp response
|
49
|
+
|
50
|
+
response_xml = response.body.content
|
51
|
+
|
52
|
+
puts "*********************"
|
53
|
+
puts Sem4r::pretty_print_xml_with_nokogiri(response_xml)
|
54
|
+
end
|
55
|
+
|
56
|
+
def send_oauth(service_url, soap_action, filename)
|
57
|
+
puts "** #{service_url}"
|
58
|
+
|
59
|
+
request_xml = read_message(filename)
|
60
|
+
puts Sem4r::pretty_print_xml_with_nokogiri(request_xml)
|
61
|
+
|
62
|
+
headers = {
|
63
|
+
"Content-Type" => "text/xml; charset=utf-8",
|
64
|
+
"Content-Length" => request_xml.length.to_s,
|
65
|
+
"SOAPAction" => soap_action}
|
66
|
+
|
67
|
+
client = Signet::OAuth1::Client.new(
|
68
|
+
:temporary_credential_uri =>
|
69
|
+
'https://www.google.com/accounts/OAuthGetRequestToken',
|
70
|
+
:authorization_uri =>
|
71
|
+
'https://www.google.com/accounts/OAuthAuthorizeToken',
|
72
|
+
:token_credential_uri =>
|
73
|
+
'https://www.google.com/accounts/OAuthGetAccessToken',
|
74
|
+
:client_credential_key => 'anonymous',
|
75
|
+
:client_credential_secret => 'anonymous',
|
76
|
+
:token_credential_key => @token_credential_key,
|
77
|
+
:token_credential_secret => @token_credential_secret
|
78
|
+
)
|
79
|
+
|
80
|
+
request = client.generate_authenticated_request(
|
81
|
+
:method => "POST",
|
82
|
+
:uri => service_url,
|
83
|
+
:headers => headers,
|
84
|
+
:body => request_xml
|
85
|
+
)
|
86
|
+
|
87
|
+
auth_header = request[2].select { |k,v| k == "Authorization" }
|
88
|
+
v = auth_header[0][1]
|
89
|
+
|
90
|
+
headers["Authorization"] = v
|
91
|
+
pp headers
|
92
|
+
|
93
|
+
client = HTTPClient.new(:agent_name => 'Ruby')
|
94
|
+
|
95
|
+
response = client.post(service_url, request_xml, headers)
|
96
|
+
# pp response
|
97
|
+
|
98
|
+
response_xml = response.body.content
|
99
|
+
|
100
|
+
puts "*********************"
|
101
|
+
puts Sem4r::pretty_print_xml_with_nokogiri(response_xml)
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def read_message(filename)
|
106
|
+
requests_xml_dir = File.expand_path(File.join(File.dirname(__FILE__), "requests_xml"))
|
107
|
+
unless File.directory?(requests_xml_dir)
|
108
|
+
puts "#{requests_xml_dir} not exists"
|
109
|
+
exit
|
110
|
+
end
|
111
|
+
|
112
|
+
var_for_erb = VarForErb.new
|
113
|
+
var_for_erb.email = @email
|
114
|
+
var_for_erb.password = @password
|
115
|
+
var_for_erb.auth_token = @auth_token
|
116
|
+
var_for_erb.developer_token = "#{@email}++EUR"
|
117
|
+
var_for_erb.client_email = "client_1+#{@email}"
|
118
|
+
|
119
|
+
filepath = File.join(requests_xml_dir, filename)
|
120
|
+
template_request_xml = File.read(filepath)
|
121
|
+
template = ERB.new(template_request_xml)
|
122
|
+
request_xml = template.result(var_for_erb.get_binding)
|
123
|
+
request_xml
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# ClientLogin
|
128
|
+
#
|
129
|
+
def authorize_token(force = false)
|
130
|
+
return @auth_token unless force or @auth_token.nil?
|
131
|
+
url = "https://www.google.com/accounts/ClientLogin"
|
132
|
+
body = "accountType=GOOGLE&Email=#{URI.escape(@email)}&Passwd=#{URI.escape(@password)}&service=adwords"
|
133
|
+
headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
|
134
|
+
|
135
|
+
|
136
|
+
client = HTTPClient.new(:agent_name => 'Ruby')
|
137
|
+
response = client.post(url, body, headers)
|
138
|
+
|
139
|
+
#pp response
|
140
|
+
#pp response.body
|
141
|
+
|
142
|
+
if response.status < 400
|
143
|
+
# pp response.body.content
|
144
|
+
end
|
145
|
+
@auth_token = response.body.content[/Auth=(.*)/, 1]
|
146
|
+
@options["auth_token"] = @auth_token
|
147
|
+
|
148
|
+
Sem4r::Profile.save_passwords("auth_token", @options, @config)
|
149
|
+
@auth_token
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
def oauth
|
154
|
+
client = Signet::OAuth1::Client.new(
|
155
|
+
:temporary_credential_uri =>
|
156
|
+
'https://www.google.com/accounts/OAuthGetRequestToken',
|
157
|
+
:authorization_uri =>
|
158
|
+
'https://www.google.com/accounts/OAuthAuthorizeToken',
|
159
|
+
:token_credential_uri =>
|
160
|
+
'https://www.google.com/accounts/OAuthGetAccessToken',
|
161
|
+
:client_credential_key => 'anonymous',
|
162
|
+
:client_credential_secret => 'anonymous'
|
163
|
+
)
|
164
|
+
|
165
|
+
# ""https://{server}/api/adwords/",
|
166
|
+
# where {server} is either
|
167
|
+
# "adwords.google.com" or "adwords-sandbox.google.com".
|
168
|
+
|
169
|
+
client.fetch_temporary_credential!(:additional_parameters => {
|
170
|
+
# :scope => 'https://mail.google.com/mail/feed/atom'
|
171
|
+
:scope => "https://adwords-sandbox.google.com/api/adwords/"
|
172
|
+
})
|
173
|
+
|
174
|
+
puts "go to this url: #{client.authorization_uri}"
|
175
|
+
puts "and type authorization here: "
|
176
|
+
verifier = gets.chop
|
177
|
+
puts "authorization is '#{verifier}'"
|
178
|
+
client.fetch_token_credential!(:verifier => verifier)
|
179
|
+
|
180
|
+
puts "client_credential_key #{client.client_credential_key}"
|
181
|
+
puts "client_credential_secret #{client.client_credential_secret}"
|
182
|
+
|
183
|
+
puts "token_credential_key #{client.token_credential_key}"
|
184
|
+
puts "token_credential_secret #{client.token_credential_secret}"
|
185
|
+
|
186
|
+
@options["token_credential_key"] = client.token_credential_key
|
187
|
+
@options["token_credential_secret"] = client.token_credential_secret
|
188
|
+
Sem4r::Profile.save_passwords("token_credential_key", @options, @config)
|
189
|
+
Sem4r::Profile.save_passwords("token_credential_secret", @options, @config)
|
190
|
+
# response = client.fetch_protected_resource(
|
191
|
+
# :uri => 'https://mail.google.com/mail/feed/atom'
|
192
|
+
# )
|
193
|
+
|
194
|
+
# The Rack response format is used here
|
195
|
+
# status, headers, body = response
|
196
|
+
|
197
|
+
# puts body
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
@@ -0,0 +1,31 @@
|
|
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
|
+
require 'uri'
|
26
|
+
require 'pp'
|
27
|
+
require 'erb'
|
28
|
+
require 'signet/oauth_1/client'
|
29
|
+
|
30
|
+
require 'sem4r'
|
31
|
+
require 'sem4r_debug_client/client'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Sem4rSinatra
|
3
|
+
#
|
4
|
+
# Build a catalogue starting from a directory
|
5
|
+
#
|
6
|
+
class CliServer
|
7
|
+
|
8
|
+
def self.run
|
9
|
+
return self.new.parse_args( ARGV )
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse_args( argv )
|
13
|
+
options = { :verbose => true, :force => false }
|
14
|
+
opts = OptionParser.new
|
15
|
+
opts.banner << " <catalog name>\n"
|
16
|
+
opts.banner << "launch a webs server to browse the content of <catalog name>\n";
|
17
|
+
opts.banner << "\n"
|
18
|
+
|
19
|
+
opts.on("-h", "--help", "Print this message") do
|
20
|
+
puts opts
|
21
|
+
return 0
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("--version", "show the simple catalog version") do
|
25
|
+
puts "simple catalog version #{SimpleCatalog::version}"
|
26
|
+
return 0
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
30
|
+
options[:verbose] = v
|
31
|
+
end
|
32
|
+
|
33
|
+
rest = opts.parse(argv)
|
34
|
+
#
|
35
|
+
# main
|
36
|
+
#
|
37
|
+
|
38
|
+
# catalog = Catalog.new(catalog_name)
|
39
|
+
WebServer.run! :host => 'localhost', :port => 9091 #, :catalog => catalog
|
40
|
+
|
41
|
+
0
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Sem4rSinatra
|
3
|
+
module Helpers
|
4
|
+
|
5
|
+
def partial(template, *args)
|
6
|
+
options = args.extract_options!
|
7
|
+
options.merge!(:layout => false)
|
8
|
+
if collection = options.delete(:collection) then
|
9
|
+
collection.inject([]) do |buffer, member|
|
10
|
+
buffer << haml(template, options.merge(
|
11
|
+
:layout => false,
|
12
|
+
:locals => {template.to_sym => member}
|
13
|
+
)
|
14
|
+
)
|
15
|
+
end.join("\n")
|
16
|
+
else
|
17
|
+
haml(template, options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def partial_erb(template)
|
22
|
+
erb template
|
23
|
+
end
|
24
|
+
|
25
|
+
def base_url
|
26
|
+
if Sinatra::Application.port == 80
|
27
|
+
"http://#{Sinatra::Application.host}/"
|
28
|
+
else
|
29
|
+
"http://#{Sinatra::Application.host}:#{Sinatra::Application.port}/"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def when_updated(time)
|
34
|
+
days = (Time.now - time) / (60 * 60 * 24)
|
35
|
+
case days.to_i
|
36
|
+
when 0
|
37
|
+
"today"
|
38
|
+
when 1
|
39
|
+
"yesterday"
|
40
|
+
else
|
41
|
+
"#{sprintf("%i", days) } days ago"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def gen_url(field, visible_field = nil)
|
46
|
+
visible_field ||= field
|
47
|
+
pos = request.env['REQUEST_URI'].index "?"
|
48
|
+
url = if pos
|
49
|
+
request.env['REQUEST_URI'][0...pos]
|
50
|
+
else
|
51
|
+
request.env['REQUEST_URI']
|
52
|
+
end
|
53
|
+
"<a href='#{url}?order=#{field}'>#{visible_field}</a>"
|
54
|
+
end
|
55
|
+
|
56
|
+
def rfc_3339(timestamp)
|
57
|
+
timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Sem4rSinatra
|
3
|
+
|
4
|
+
class WebServer < Sinatra::Base
|
5
|
+
|
6
|
+
# turns on static file serving for Sinatra::Base apps
|
7
|
+
enable :static
|
8
|
+
|
9
|
+
server_dir = File.expand_path(File.join(File.dirname(__FILE__)))
|
10
|
+
set :public, File.join(server_dir, 'public')
|
11
|
+
set :views, File.join(server_dir, 'views')
|
12
|
+
|
13
|
+
helpers do
|
14
|
+
include Rack::Utils
|
15
|
+
alias_method :h, :escape_html
|
16
|
+
end
|
17
|
+
|
18
|
+
helpers Helpers
|
19
|
+
|
20
|
+
get '/app.css' do
|
21
|
+
content_type 'text/css', :charset => 'utf-8'
|
22
|
+
sass :app
|
23
|
+
end
|
24
|
+
|
25
|
+
# get "/js/tooltips/tooltips.css" do
|
26
|
+
# content_type 'text/css', :charset => 'utf-8'
|
27
|
+
# sass "/js/tooltips/tooltips".to_sym
|
28
|
+
# end
|
29
|
+
|
30
|
+
get '/' do
|
31
|
+
# haml :items
|
32
|
+
"Hello Sem4r"
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
#######################################################################################
|
37
|
+
# Ajax
|
38
|
+
|
39
|
+
get '/ajax/ajax_item/:id' do
|
40
|
+
# @item = Item.get(params[:id])
|
41
|
+
# haml 'ajax/ajax_item'.to_sym, :layout => false
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'haml'
|
5
|
+
require 'sass'
|
6
|
+
require 'json'
|
7
|
+
require 'optparse'
|
8
|
+
|
9
|
+
require 'sem4r'
|
10
|
+
|
11
|
+
require 'sem4r_sinatra/helpers'
|
12
|
+
require 'sem4r_sinatra/web_server'
|
13
|
+
require 'sem4r_sinatra/cli_server'
|
@@ -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 Sem4rSoap
|
@@ -93,7 +92,7 @@ module Sem4rSoap
|
|
93
92
|
uri = URI.parse(uri) # might raise URI::InvalidURIError
|
94
93
|
end
|
95
94
|
retries = 0; response = nil
|
96
|
-
while retries <=
|
95
|
+
while retries <= MAX_RETRIES and response.nil?
|
97
96
|
retries += 1
|
98
97
|
begin
|
99
98
|
client = client_for_uri(uri)
|
@@ -116,7 +115,7 @@ module Sem4rSoap
|
|
116
115
|
|
117
116
|
private
|
118
117
|
|
119
|
-
|
118
|
+
MAX_RETRIES = 2
|
120
119
|
|
121
120
|
def client_for_uri(uri)
|
122
121
|
@clients ||= {}
|
@@ -179,7 +178,7 @@ module Sem4rSoap
|
|
179
178
|
# Downloads content at url in path_name
|
180
179
|
#
|
181
180
|
def download(url, path_name)
|
182
|
-
client = HTTPClient.new(:agent_name => 'Ruby')
|
181
|
+
client = HTTPClient.new(:agent_name => 'Ruby')
|
183
182
|
File.open(path_name, "w") do |file|
|
184
183
|
client.get_content(url) do |chunk|
|
185
184
|
file.write chunk
|
@@ -188,10 +187,10 @@ module Sem4rSoap
|
|
188
187
|
end
|
189
188
|
|
190
189
|
#
|
191
|
-
# @return [Object] must respond to :status and :body
|
190
|
+
# @return [Object, #status, #body] must respond to :status and :body
|
192
191
|
#
|
193
192
|
def post(service_url, body, headers)
|
194
|
-
client = HTTPClient.new(:agent_name => 'Ruby')
|
193
|
+
client = HTTPClient.new(:agent_name => 'Ruby')
|
195
194
|
response = client.post(service_url, body, headers)
|
196
195
|
unless response
|
197
196
|
raise "Connection Error, Network is down?? :-((("
|
@@ -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 Sem4rSoap
|
@@ -55,6 +54,7 @@ module Sem4rSoap
|
|
55
54
|
@soap_dump_interceptor = options[:interceptor] if options[:interceptor]
|
56
55
|
end
|
57
56
|
|
57
|
+
# TODO: request_xml might be a doc object as Nokogiri::doc
|
58
58
|
def dump_soap_request(service_url, request_xml)
|
59
59
|
return unless @soap_dump
|
60
60
|
%w{email password developerToken authToken clientEmail}.each do |tag|
|
@@ -66,6 +66,7 @@ module Sem4rSoap
|
|
66
66
|
dump(service_url, "req", str)
|
67
67
|
end
|
68
68
|
|
69
|
+
# TODO: response_xml might be a doc object as Nokogiri::doc
|
69
70
|
def dump_soap_response(service_url, response_xml)
|
70
71
|
return unless @soap_dump
|
71
72
|
response_xml.gsub(/<email[^>]*>.+<\/email>/, "<email>**censured**</email>")
|
@@ -101,19 +102,7 @@ module Sem4rSoap
|
|
101
102
|
if !@soap_dump_format
|
102
103
|
xml
|
103
104
|
else
|
104
|
-
|
105
|
-
require 'rexml/document'
|
106
|
-
begin
|
107
|
-
xml_document = REXML::Document.new(xml)
|
108
|
-
f = REXML::Formatters::Pretty.new
|
109
|
-
out = String.new
|
110
|
-
f.write(xml_document, out)
|
111
|
-
# remove xml directive
|
112
|
-
out.gsub("<?xml version='1.0' encoding='UTF-8'?>", "")
|
113
|
-
rescue
|
114
|
-
puts xml
|
115
|
-
raise
|
116
|
-
end
|
105
|
+
Sem4r::pretty_print_xml_with_nokogiri(xml)
|
117
106
|
end
|
118
107
|
end
|
119
108
|
end
|