ape 1.0.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/README +22 -8
- data/Rakefile +66 -0
- data/bin/ape_server +3 -3
- data/lib/ape.rb +131 -937
- data/lib/ape/atomURI.rb +1 -1
- data/lib/ape/authent.rb +11 -17
- data/lib/ape/categories.rb +8 -7
- data/lib/ape/collection.rb +3 -7
- data/lib/ape/crumbs.rb +1 -1
- data/lib/ape/entry.rb +1 -1
- data/lib/ape/escaper.rb +1 -1
- data/lib/ape/feed.rb +26 -14
- data/lib/ape/handler.rb +8 -3
- data/lib/ape/html.rb +1 -1
- data/lib/ape/invoker.rb +1 -1
- data/lib/ape/invokers/deleter.rb +1 -1
- data/lib/ape/invokers/getter.rb +1 -1
- data/lib/ape/invokers/poster.rb +1 -1
- data/lib/ape/invokers/putter.rb +1 -1
- data/lib/ape/names.rb +1 -1
- data/lib/ape/print_writer.rb +4 -6
- data/lib/ape/reporter.rb +156 -0
- data/lib/ape/reporters/atom_reporter.rb +51 -0
- data/lib/ape/reporters/atom_template.eruby +38 -0
- data/lib/ape/reporters/html_reporter.rb +53 -0
- data/lib/ape/reporters/html_template.eruby +62 -0
- data/lib/ape/reporters/text_reporter.rb +37 -0
- data/lib/ape/samples.rb +30 -51
- data/lib/ape/server.rb +16 -4
- data/lib/ape/service.rb +1 -1
- data/lib/ape/util.rb +67 -0
- data/lib/ape/validator.rb +85 -57
- data/lib/ape/validator_dsl.rb +40 -0
- data/lib/ape/validators/entry_posts_validator.rb +226 -0
- data/lib/ape/validators/media_linkage_validator.rb +78 -0
- data/lib/ape/validators/media_posts_validator.rb +104 -0
- data/lib/ape/validators/sanitization_validator.rb +57 -0
- data/lib/ape/validators/schema_validator.rb +57 -0
- data/lib/ape/validators/service_document_validator.rb +64 -0
- data/lib/ape/validators/sorting_validator.rb +87 -0
- data/lib/ape/version.rb +1 -1
- data/{lib/ape/samples → samples}/atom_schema.txt +0 -0
- data/{lib/ape/samples → samples}/basic_entry.eruby +4 -4
- data/{lib/ape/samples → samples}/categories_schema.txt +0 -0
- data/{lib/ape/samples → samples}/mini_entry.eruby +0 -0
- data/{lib/ape/samples → samples}/service_schema.txt +0 -0
- data/{lib/ape/samples → samples}/unclean_xhtml_entry.eruby +0 -0
- data/test/test_helper.rb +33 -1
- data/test/unit/ape_test.rb +92 -0
- data/test/unit/authent_test.rb +2 -2
- data/test/unit/reporter_test.rb +102 -0
- data/test/unit/samples_test.rb +2 -2
- data/test/unit/validators_test.rb +50 -0
- data/{lib/ape/layout → web}/ape.css +5 -1
- data/{lib/ape/layout → web}/ape_logo.png +0 -0
- data/{lib/ape/layout → web}/index.html +2 -5
- data/{lib/ape/layout → web}/info.png +0 -0
- metadata +108 -56
- data/CHANGELOG +0 -1
- data/Manifest +0 -45
- data/ape.gemspec +0 -57
- data/scripts/go.rb +0 -29
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# To change this template, choose Tools | Templates
|
3
|
+
# and open the template in the editor.
|
4
|
+
|
5
|
+
|
6
|
+
module Ape
|
7
|
+
class AtomReporter < Reporter
|
8
|
+
def escape(text)
|
9
|
+
Escaper.escape(text)
|
10
|
+
end
|
11
|
+
|
12
|
+
def now
|
13
|
+
DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
14
|
+
end
|
15
|
+
|
16
|
+
def id
|
17
|
+
id = ''
|
18
|
+
5.times { id += rand(1000000).to_s }
|
19
|
+
"tag:tbray.org,2005:#{id}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def content(step, dialog = nil)
|
23
|
+
xml = "<div xmlns=\"http://www.w3.org/1999/xhtml\">"
|
24
|
+
lines = step.split("\n")
|
25
|
+
lines[0 .. -2].each do |line|
|
26
|
+
xml += "#{line} <br/>"
|
27
|
+
end
|
28
|
+
xml += escape(lines[-1]) if lines[-1]
|
29
|
+
if dialog && dialogs[dialog]
|
30
|
+
xml += '<div>'
|
31
|
+
xml += 'To server:'
|
32
|
+
dialogs[dialog].grep(/^>/).each do |crumb|
|
33
|
+
xml += show_message(crumb, :to)
|
34
|
+
end
|
35
|
+
xml += '</div>'
|
36
|
+
xml += '<div>'
|
37
|
+
xml += 'From server:'
|
38
|
+
dialogs[dialog].grep(/^</).each do |crumb|
|
39
|
+
xml += show_message(crumb, :from)
|
40
|
+
end
|
41
|
+
xml += '</div>'
|
42
|
+
end
|
43
|
+
xml += '</div>'
|
44
|
+
xml
|
45
|
+
end
|
46
|
+
|
47
|
+
def report(output = STDOUT)
|
48
|
+
output.puts evaluate_template("reporters/atom_template.eruby")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<id><%= id %></id>
|
4
|
+
<author><name>The ape</name></author>
|
5
|
+
<title>Atom Protocol Exerciser Report</title>
|
6
|
+
<updated><%= now %></updated>
|
7
|
+
<subtitle><%= errors.length == 1?"1 error":"#{errors.length} errors"%>, <%= warnings.length == 1?"1 warning":"#{warnings.length} warnings"%></subtitle>
|
8
|
+
<% steps.each do |step| %>
|
9
|
+
<% if step.kind_of?(Array) %>
|
10
|
+
<entry>
|
11
|
+
<id><%= id %></id>
|
12
|
+
<title type="html"><%= "INFO: #{step[0]}"%></title>
|
13
|
+
<updated><%= now %></updated>
|
14
|
+
<category term="info"/>
|
15
|
+
<content type="xhtml">
|
16
|
+
<% step[1..-1].each do |li| %>
|
17
|
+
<%= content(li[:message]) %>
|
18
|
+
<% end %>
|
19
|
+
</content>
|
20
|
+
</entry>
|
21
|
+
<% else %>
|
22
|
+
<% if step[:severity] == :debug %>
|
23
|
+
<% @dialog = step[:message] %>
|
24
|
+
<% else %>
|
25
|
+
<entry>
|
26
|
+
<id><%= id %></id>
|
27
|
+
<title type="html"><%= step[:severity].to_s.upcase%>: <%= step[:message] %></title>
|
28
|
+
<updated><%= now %></updated>
|
29
|
+
<category term="<%= step[:severity].to_s %>"/>
|
30
|
+
<content type="xhtml">
|
31
|
+
<%= content(step[:message], @dialog) %>
|
32
|
+
</content>
|
33
|
+
</entry>
|
34
|
+
<% @dialog = nil %>
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
37
|
+
<% end %>
|
38
|
+
</feed>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
module Ape
|
3
|
+
class HtmlReporter < Reporter
|
4
|
+
|
5
|
+
def static_dir
|
6
|
+
dir = (server != true)?File.expand_path(File.dirname(__FILE__) + '/../../..') : ''
|
7
|
+
dir += "/web"
|
8
|
+
dir
|
9
|
+
end
|
10
|
+
|
11
|
+
def stylesheet
|
12
|
+
static_dir + '/ape.css'
|
13
|
+
end
|
14
|
+
|
15
|
+
def mark(mark)
|
16
|
+
span = "<span class=\"#{mark.to_s}\">"
|
17
|
+
case mark
|
18
|
+
when :success
|
19
|
+
span << '✓' << '</span>'
|
20
|
+
when :warning
|
21
|
+
span << '?' << '</span>'
|
22
|
+
when :error
|
23
|
+
span << '!' << '</span>'
|
24
|
+
when :info
|
25
|
+
span = "<img class=\"info\" src=\"#{static_dir + '/info.png'}\"/>"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def report_li(step, dialog = nil, marker = nil)
|
30
|
+
html = '<li>'
|
31
|
+
if marker
|
32
|
+
html += "#{mark(marker)} "
|
33
|
+
end
|
34
|
+
# preserve line-breaks in output
|
35
|
+
lines = step.split("\n")
|
36
|
+
lines[0 .. -2].each do |line|
|
37
|
+
html += "#{line} <br/>"
|
38
|
+
end
|
39
|
+
html += lines[-1] if lines[-1]
|
40
|
+
if dialog
|
41
|
+
html += "<a class=\"diaref\" href=\"#dia-#{@dianum}\">[Dialog]</a>"
|
42
|
+
@diarefs[dialog] = @dianum
|
43
|
+
@dianum += 1
|
44
|
+
end
|
45
|
+
html += '</li>'
|
46
|
+
html
|
47
|
+
end
|
48
|
+
|
49
|
+
def report(output = STDOUT)
|
50
|
+
output.puts evaluate_template("reporters/html_template.eruby")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Atom Protocol Exerciser Report</title>
|
4
|
+
<link rel="stylesheet" type="text/css" href="<%= stylesheet %>" />
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<h2>The Ape says:</h2>
|
8
|
+
<% if header %>
|
9
|
+
<p><%= header %></p>
|
10
|
+
<p>Summary: <%= errors.length == 1?"1 error":"#{errors.length} errors"%>,
|
11
|
+
<%= warnings.length == 1?"1 warning":"#{warnings.length} warnings"%>
|
12
|
+
</p>
|
13
|
+
<% end %>
|
14
|
+
<ol id="steps">
|
15
|
+
<% steps.each do |step| %>
|
16
|
+
<% if step.kind_of?(Array) %>
|
17
|
+
<li>
|
18
|
+
<p><%= mark(:info) %> <%= step[0] %></p>
|
19
|
+
<ul>
|
20
|
+
<% step[1..-1].each do |li| %>
|
21
|
+
<%= report_li(li[:message]) %>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
24
|
+
</li>
|
25
|
+
<% else %>
|
26
|
+
<% if step[:severity] == :debug %>
|
27
|
+
<% @dialog = step[:message] %>
|
28
|
+
<% else %>
|
29
|
+
<%= report_li(step[:message], @dialog, step[:severity])%>
|
30
|
+
<% @dialog = nil %>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
34
|
+
</ol>
|
35
|
+
|
36
|
+
<% if footer %>
|
37
|
+
<p><%= footer %></p>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<% unless dialogs.empty? %>
|
41
|
+
<h2>Recorded client/server dialogs</h2>
|
42
|
+
<% diarefs.each do |k, v| %>
|
43
|
+
<% @dialog = @dialogs[k] %>
|
44
|
+
<h3 id="<%="dia-#{v}"%>"><%= k %></h3>
|
45
|
+
<div class="dialog">
|
46
|
+
<div class="dialab">
|
47
|
+
To server:
|
48
|
+
<% @dialog.grep(/^>/).each do |crumb| %>
|
49
|
+
<%= show_message(crumb, :to) %>
|
50
|
+
<% end %>
|
51
|
+
</div>
|
52
|
+
<div class="dialab">
|
53
|
+
From server:
|
54
|
+
<% @dialog.grep(/^</).each do |crumb| %>
|
55
|
+
<%= show_message(crumb, :from) %>
|
56
|
+
<% end %>
|
57
|
+
</div>
|
58
|
+
</div>
|
59
|
+
<% end %>
|
60
|
+
<% end %>
|
61
|
+
</body>
|
62
|
+
</html>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Ape
|
2
|
+
class TextReporter < Reporter
|
3
|
+
def report(output = STDOUT)
|
4
|
+
if @header
|
5
|
+
output.puts @header
|
6
|
+
output.puts errors.length == 1?"1 error":"#{errors.length} errors"
|
7
|
+
output.puts warnings.length == 1?"1 warning":"#{warnings.length} warnings"
|
8
|
+
end
|
9
|
+
steps.each do |step|
|
10
|
+
if step.class == Crumbs
|
11
|
+
output.puts " Dialog:"
|
12
|
+
step.each { |crumb| output.puts " #{crumb}" }
|
13
|
+
else
|
14
|
+
line
|
15
|
+
if (step.kind_of?Array)
|
16
|
+
output.puts "INFO: #{step[0]}"
|
17
|
+
step[1..-1].each do |li|
|
18
|
+
lines = li[:message].split("\n")
|
19
|
+
lines[0..-2].each do |line|
|
20
|
+
output.puts("\t #{line} \n")
|
21
|
+
end
|
22
|
+
output.puts("\t #{lines[-1]}") if lines[-1]
|
23
|
+
end
|
24
|
+
else
|
25
|
+
case step[:severity]
|
26
|
+
when :warning, :error
|
27
|
+
output.puts "#{step[:severity].to_s.upcase}: #{step[:message]}"
|
28
|
+
else
|
29
|
+
output.puts step[:message]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
output.puts @footer if @footer
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/ape/samples.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved
|
2
2
|
# Use is subject to license terms - see file "LICENSE"
|
3
3
|
require 'rexml/xpath'
|
4
4
|
require 'date'
|
@@ -6,17 +6,23 @@ require 'base64'
|
|
6
6
|
require 'erubis'
|
7
7
|
|
8
8
|
module Ape
|
9
|
+
class SamplesContext < Erubis::Context
|
10
|
+
def now
|
11
|
+
DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
12
|
+
end
|
13
|
+
def id
|
14
|
+
id = ''
|
15
|
+
5.times { id += rand(1000000).to_s }
|
16
|
+
"tag:tbray.org,2005:#{id}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
9
20
|
class Samples
|
10
21
|
|
11
22
|
@@service_schema = nil
|
12
23
|
@@categories_schema = nil
|
13
24
|
@@atom_schema = nil
|
14
|
-
@@home = nil
|
15
25
|
|
16
|
-
def Samples.home=(home)
|
17
|
-
@@home = home
|
18
|
-
end
|
19
|
-
|
20
26
|
def Samples.foreign_child
|
21
27
|
'subject'
|
22
28
|
end
|
@@ -28,13 +34,7 @@ module Ape
|
|
28
34
|
end
|
29
35
|
|
30
36
|
def Samples.load_schema(file_name)
|
31
|
-
|
32
|
-
File.open(File.join(File.dirname(__FILE__), "/samples/#{file_name}_schema.txt")) do |file|
|
33
|
-
while(line = file.gets)
|
34
|
-
schema << line
|
35
|
-
end
|
36
|
-
end
|
37
|
-
schema
|
37
|
+
IO.read(File.join(File.dirname(__FILE__), "/../../samples/#{file_name}_schema.txt"))
|
38
38
|
end
|
39
39
|
|
40
40
|
def Samples.service_RNC
|
@@ -52,15 +52,7 @@ module Ape
|
|
52
52
|
@@atom_schema
|
53
53
|
end
|
54
54
|
|
55
|
-
#recipe from cap
|
56
|
-
def Samples.home_directory
|
57
|
-
ENV["HOME"] || (ENV["HOMEPATH"] && "#{ENV["HOMEDRIVE"]}#{ENV["HOMEPATH"]}") ||
|
58
|
-
"/"
|
59
|
-
end
|
60
55
|
|
61
|
-
def Samples.home
|
62
|
-
@@home || ENV["APE_HOME"] || File.join(home_directory,".ape")
|
63
|
-
end
|
64
56
|
|
65
57
|
def Samples.make_id
|
66
58
|
id = ''
|
@@ -69,57 +61,44 @@ module Ape
|
|
69
61
|
end
|
70
62
|
|
71
63
|
def Samples.entry_path(type)
|
72
|
-
File.exist?(File.join(home, "/#{type}.eruby"))?
|
73
|
-
File.join(home, "/#{type}.eruby") :
|
74
|
-
File.join(File.dirname(__FILE__), "
|
64
|
+
File.exist?(File.join(Ape.home, "/#{type}.eruby"))?
|
65
|
+
File.join(Ape.home, "/#{type}.eruby") :
|
66
|
+
File.join(File.dirname(__FILE__), "/../../samples/#{type}.eruby")
|
75
67
|
end
|
76
68
|
|
77
69
|
def Samples.load_template(type)
|
78
|
-
entry_path
|
79
|
-
input = File.read(entry_path)
|
80
|
-
eruby = Erubis::Eruby.new(input)
|
70
|
+
Erubis::FastEruby.new(IO.read(entry_path(type)))
|
81
71
|
end
|
82
72
|
|
83
73
|
|
84
74
|
def Samples.mini_entry
|
85
|
-
|
86
|
-
|
87
|
-
now = DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
88
|
-
id = make_id
|
89
|
-
|
90
|
-
eruby.result(binding())
|
75
|
+
load_template('mini_entry').evaluate(SamplesContext.new)
|
91
76
|
end
|
92
77
|
|
93
78
|
def Samples.basic_entry
|
94
|
-
eruby = load_template('basic_entry')
|
79
|
+
eruby = load_template('basic_entry')
|
80
|
+
|
81
|
+
context = SamplesContext.new(
|
82
|
+
:title => Escaper.escape('From the <APE> (サル)'),
|
83
|
+
:subject => Names::DcNamespace
|
84
|
+
)
|
85
|
+
context[:summary] = "Summary from the <b>&lt;&nbsp;APE&nbsp;></b> at #{context.now}"
|
95
86
|
|
96
|
-
|
97
|
-
now = DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
98
|
-
title = Escaper.escape('From the <APE> (サル)')
|
99
|
-
summary = "Summary from the <b>&lt;&nbsp;APE&nbsp;></b> at #{now}"
|
100
|
-
subject = Names::DcNamespace
|
101
|
-
|
102
|
-
eruby.result(binding())
|
87
|
+
eruby.evaluate(context)
|
103
88
|
end
|
104
89
|
|
105
90
|
def Samples.unclean_xhtml_entry
|
106
|
-
|
107
|
-
|
108
|
-
id = make_id
|
109
|
-
now = DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
110
|
-
|
111
|
-
eruby.result(binding())
|
91
|
+
load_template('unclean_xhtml_entry').evaluate(SamplesContext.new)
|
112
92
|
end
|
113
93
|
|
114
94
|
def Samples.cat_test_entry
|
115
|
-
|
95
|
+
retitled_entry('Testing category posting')
|
116
96
|
end
|
117
97
|
|
118
98
|
def Samples.retitled_entry(new_title, new_id = nil)
|
119
99
|
e = basic_entry
|
120
|
-
e.gsub!(/<title>.*<\/title>/, "<title>#{new_title}</title>")
|
121
|
-
new_id
|
122
|
-
e.gsub(/<id>.*<\/id>/, "<id>#{new_id}</id>")
|
100
|
+
e.gsub!(/<title>.*<\/title>/, "<title>#{new_title}</title>")
|
101
|
+
e.gsub(/<id>.*<\/id>/, "<id>#{new_id}</id>") if new_id
|
123
102
|
end
|
124
103
|
|
125
104
|
def Samples.picture
|
data/lib/ape/server.rb
CHANGED
@@ -4,18 +4,30 @@ require 'ape/handler'
|
|
4
4
|
require 'ape/samples'
|
5
5
|
|
6
6
|
module Ape
|
7
|
+
|
8
|
+
# Manages and initializes the Mongrel handler. See run for more details.
|
7
9
|
class Server
|
10
|
+
|
11
|
+
# Starts the Mongrel handler with options given in +options+ and
|
12
|
+
# maps the <b>/</b>, <b>/ape</b> and <b>/atompub/go</b> URIs to handlers.
|
13
|
+
#
|
14
|
+
# ==== Options
|
15
|
+
# * :host - the IP address to bind to
|
16
|
+
# * :port - the port number to listen on
|
17
|
+
# * :directory - the ape home directory
|
8
18
|
def self.run(options)
|
9
|
-
|
19
|
+
Ape.home = options[:home]
|
10
20
|
|
11
21
|
mongrel = Mongrel::Configurator.new(:host => options[:host], :port => options[:port]) do
|
12
22
|
log "=> Booting mongrel"
|
13
23
|
begin
|
14
24
|
log "=> The ape starting on http://#{options[:host]}:#{options[:port]}"
|
15
25
|
listener do
|
16
|
-
redirect '/', '/
|
17
|
-
uri '/
|
18
|
-
|
26
|
+
redirect '/', '/web/index.html'
|
27
|
+
uri '/web', :handler =>
|
28
|
+
Mongrel::DirHandler.new(
|
29
|
+
File.expand_path(File.dirname(__FILE__) + '/../../web'), true)
|
30
|
+
uri '/atompub/go', :handler => Handler.new
|
19
31
|
end
|
20
32
|
rescue Errno::EADDRINUSE
|
21
33
|
log "ERROR: Address (#{options[:host]}:#{options[:port]}) is already in use"
|
data/lib/ape/service.rb
CHANGED
data/lib/ape/util.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
module Ape
|
2
|
+
module Util
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
include InstanceMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
=begin
|
10
|
+
Get a resource, optionally check its content-type
|
11
|
+
=end
|
12
|
+
def check_resource(uri, name, content_type = nil, report = true)
|
13
|
+
resource = Getter.new(uri, @authent)
|
14
|
+
|
15
|
+
# * Check the URI
|
16
|
+
if resource.last_error
|
17
|
+
reporter.error(self, "Unacceptable #{name} URI: " + resource.last_error, name) if report
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
|
21
|
+
# * Get it, make sure it has the right content-type
|
22
|
+
worked = resource.get(content_type)
|
23
|
+
reporter.save_dialog(name, resource)
|
24
|
+
|
25
|
+
reporter.security_warning(self) if (resource.security_warning)
|
26
|
+
|
27
|
+
if !worked
|
28
|
+
# oops, couldn't even get get it
|
29
|
+
reporter.error(self, "#{name} failed: " + resource.last_error, name) if report
|
30
|
+
return nil
|
31
|
+
|
32
|
+
elsif resource.last_error
|
33
|
+
# oops, media-type problem
|
34
|
+
reporter.error(self, "#{name}: #{resource.last_error}", name) if report
|
35
|
+
|
36
|
+
else
|
37
|
+
# resource fetched and is of right type
|
38
|
+
reporter.success(self, "#{name}: it exists and is served properly.", name) if report
|
39
|
+
end
|
40
|
+
|
41
|
+
return resource
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
=begin
|
47
|
+
Resolve extensions into the lib directory or into the ape home directory. These extensions could be validators,
|
48
|
+
resolvers or samples.
|
49
|
+
=end
|
50
|
+
def resolve_plugin(key, dir, suffix, drop_underlines = false)
|
51
|
+
[File.dirname(__FILE__), Ape.home].each do |path|
|
52
|
+
Dir[File.join(path, "#{dir}/*.rb")].each do |file|
|
53
|
+
require file
|
54
|
+
plugin_name = file.gsub(/(.+\/#{dir}\/)(.+)(_#{suffix}.rb)/, '\2')
|
55
|
+
plugin_name.gsub!(/_/, '') if drop_underlines
|
56
|
+
plugin_class = file.gsub(/(.+\/#{dir}\/)(.+)(.rb)/, '\2').gsub(/(^|_)(.)/) { $2.upcase }
|
57
|
+
|
58
|
+
if (key.to_s.strip.downcase.include?(plugin_name))
|
59
|
+
return eval("#{plugin_class}.new", binding, __FILE__, __LINE__)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|