flurin-html_mockup 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +81 -0
- data/bin/mockup +5 -0
- data/examples/html/green.gif +0 -0
- data/examples/html/index.html +18 -0
- data/examples/partials/test.part.rhtml +3 -0
- data/examples/script/server +14 -0
- data/lib/html_mockup/cli.rb +133 -0
- data/lib/html_mockup/rack/html_mockup.rb +47 -0
- data/lib/html_mockup/rack/html_validator.rb +26 -0
- data/lib/html_mockup/template.rb +124 -0
- data/lib/html_mockup/w3c_validator.rb +120 -0
- metadata +82 -0
data/README.rdoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
== HtmlMockup
|
2
|
+
|
3
|
+
HTML Mockup is a set of tools to create self-containing HTML mockups. HtmlMockup gives you the flexibility
|
4
|
+
of a templatinglanguage but at the same time keeps all HTML files viewable. HTML comments are
|
5
|
+
used to determine what partial (sub-template) to render.
|
6
|
+
|
7
|
+
HtmlMockup also provides tools for HTML validation.
|
8
|
+
|
9
|
+
=== Requirements
|
10
|
+
HtmlMockup requires the following dependencies
|
11
|
+
|
12
|
+
* Ruby 1.8.x (not tested in 1.9.x)
|
13
|
+
* Rubygems
|
14
|
+
* Thor (to use mockup binary)
|
15
|
+
* Rack > 0.3 (to use mockup serve)
|
16
|
+
|
17
|
+
=== Usage
|
18
|
+
|
19
|
+
Just write regular HTML files and include comment's like this:
|
20
|
+
|
21
|
+
<!-- [START:partial_name] -->Text<!-- [STOP:partial_name] -->
|
22
|
+
|
23
|
+
The data between the tags will be replaced by the partial contents. Partials are searched in
|
24
|
+
"../partials" relative to the directory the script you run resides in. This can be overridden with
|
25
|
+
commandline parameters. Partials always must have a .part.r?html ending and are evaluated as ERB during
|
26
|
+
insertion.
|
27
|
+
|
28
|
+
=== Syntax for HTML files
|
29
|
+
|
30
|
+
==== Standard partials
|
31
|
+
|
32
|
+
<!-- [START:partial_name] -->Text<!-- [STOP:partial_name] -->
|
33
|
+
|
34
|
+
==== Pass parameters to partials
|
35
|
+
|
36
|
+
You can pass in parameters to partials in the format of key=value&key2=value2 (it's just a regular CGI
|
37
|
+
query string and is parsed by CGI#parse). The partials wich are evaluated as ERB can access the variables
|
38
|
+
through standard instance methods. The example below would create the instance variable @key.
|
39
|
+
|
40
|
+
<!-- [START:partial_name?key=value] -->Text<!-- [STOP:partial_name] -->
|
41
|
+
|
42
|
+
|
43
|
+
=== Mockup commandline
|
44
|
+
|
45
|
+
==== mockup convert [directory/file]
|
46
|
+
|
47
|
+
Convert can be called with a single html file or a directory. If a directory is specified all .html files
|
48
|
+
will be converted.
|
49
|
+
|
50
|
+
*Warning:* Convert will overwrite the file itself!
|
51
|
+
|
52
|
+
Options:
|
53
|
+
--partial_path:: the path where the partial files can be found (*.part.html), defaults to director/../partials
|
54
|
+
--filter:: The filter to use when finding templates within directory, defaults to *.html
|
55
|
+
|
56
|
+
==== mockup serve [directory/file]
|
57
|
+
|
58
|
+
Serve can be used during development as a simple webserver (Webrick/Mongrel). It also supports
|
59
|
+
on-the-fly HTML validation.
|
60
|
+
|
61
|
+
You can also call ./script/server just above the HTML directory.
|
62
|
+
|
63
|
+
Options:
|
64
|
+
--port:: The port the server should listen on. Defaults to 9000
|
65
|
+
--partial_path:: the path where the partial files can be found (*.part.html), defaults to director/../partials
|
66
|
+
--validate:: Flag to set wether or not we should validate all html files (defaults to false)
|
67
|
+
|
68
|
+
==== mockup generate [directory]
|
69
|
+
|
70
|
+
Generate creates a directory structure in directory for use with new HTML mockups.
|
71
|
+
|
72
|
+
==== mockup validate [directory/file]
|
73
|
+
|
74
|
+
Validates all files within directory or just file with the W3C validator webservice.
|
75
|
+
|
76
|
+
Options:
|
77
|
+
--show_valid:: Flag to print a line for each valid file too (defaults to false)
|
78
|
+
--filter:: What files should be validated, defaults to [^_]*.html
|
79
|
+
|
80
|
+
=== Copyright & license
|
81
|
+
Copyright (c) 2009 Flurin Egger, DigitPaint, MIT Style License. (see MIT-LICENSE)
|
data/bin/mockup
ADDED
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
7
|
+
|
8
|
+
<title>untitled</title>
|
9
|
+
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<!-- [START:test?id=bla] -->
|
14
|
+
<!-- [STOP:test] -->
|
15
|
+
|
16
|
+
<img src="green.gif" alt="Green" />
|
17
|
+
</body>
|
18
|
+
</html>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require File.dirname(__FILE__) + "/../vendor/html_mockup/lib/html_mockup/cli"
|
5
|
+
rescue LoadError => e
|
6
|
+
require 'rubygems'
|
7
|
+
require 'html_mockup/cli'
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
a = ARGV.dup
|
12
|
+
a.unshift(File.dirname(__FILE__) + "/../html")
|
13
|
+
a.unshift("serve")
|
14
|
+
HtmlMockup::Cli.start(a)
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
require 'fileutils'
|
6
|
+
include FileUtils
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + "/template"
|
9
|
+
require File.dirname(__FILE__) + "/w3c_validator"
|
10
|
+
|
11
|
+
module HtmlMockup
|
12
|
+
class Cli < Thor
|
13
|
+
desc "serve [directory]","Serve directory as HTML, defaults to current directory"
|
14
|
+
method_options :port => :optional, # Defaults to 9000
|
15
|
+
:partial_path => :optional, # Defaults to [directory]/../partials
|
16
|
+
:validate => :boolean # Automatically validate all HTML responses @ the w3c
|
17
|
+
def serve(path=".")
|
18
|
+
@path,@partial_path = template_paths(path,options["partial_path"])
|
19
|
+
require 'rack'
|
20
|
+
require File.dirname(__FILE__) + "/rack/html_mockup"
|
21
|
+
require File.dirname(__FILE__) + "/rack/html_validator"
|
22
|
+
chain = ::Rack::Builder.new do
|
23
|
+
use ::Rack::ShowExceptions
|
24
|
+
use ::Rack::Lint
|
25
|
+
end
|
26
|
+
chain.use Rack::HtmlValidator if options["validate"]
|
27
|
+
chain.run Rack::HtmlMockup.new(@path, @partial_path)
|
28
|
+
|
29
|
+
begin
|
30
|
+
server = ::Rack::Handler::Mongrel
|
31
|
+
rescue LoadError => e
|
32
|
+
server = ::Rack::Handler::WEBrick
|
33
|
+
end
|
34
|
+
|
35
|
+
server_options = {}
|
36
|
+
server_options[:Port] = options["port"] || "9000"
|
37
|
+
|
38
|
+
puts "Running #{server.inspect} on port #{server_options[:Port]}"
|
39
|
+
server.run chain.to_app, server_options
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "validate [directory/file]", "Validates the file or all HTML in directory"
|
43
|
+
method_options :show_valid => :boolean, # Also print a line for each valid file
|
44
|
+
:filter => :optional # What files should be found, defaults to [^_]*.html
|
45
|
+
def validate(path=".")
|
46
|
+
filter = options["filter"] || "[^_]*.html"
|
47
|
+
|
48
|
+
puts "Filtering on #{options["filter"]}" if options["filter"]
|
49
|
+
|
50
|
+
if File.directory?(path)
|
51
|
+
any_invalid = false
|
52
|
+
|
53
|
+
if (files = Dir.glob("#{path}/**/#{filter}")).any?
|
54
|
+
files.each do |file|
|
55
|
+
if !self.w3cvalidate(file)
|
56
|
+
any_invalid = true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
if !any_invalid
|
60
|
+
puts "All files were considered valid"
|
61
|
+
end
|
62
|
+
else
|
63
|
+
puts "No files matched \"#{filter}\""
|
64
|
+
end
|
65
|
+
elsif File.readable?(path)
|
66
|
+
self.w3cvalidate(path)
|
67
|
+
else
|
68
|
+
puts "No such file/directory #{path}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "generate [directory]","Create a new HTML mockup directory tree in directory"
|
73
|
+
def generate(path)
|
74
|
+
path = Pathname.new(path)
|
75
|
+
if path.directory?
|
76
|
+
puts "Directory #{path} already exists, please only use this to create new mockups"
|
77
|
+
else
|
78
|
+
example_path = Pathname.new(File.dirname(__FILE__) + "/../../examples")
|
79
|
+
path.mkpath
|
80
|
+
html_path = path + "html"
|
81
|
+
mkdir(html_path)
|
82
|
+
mkdir(html_path + "stylesheets")
|
83
|
+
mkdir(html_path + "images")
|
84
|
+
mkdir(html_path + "javascripts")
|
85
|
+
|
86
|
+
mkdir(path + "partials")
|
87
|
+
|
88
|
+
mkdir(path + "script")
|
89
|
+
cp(example_path + "script/server",path + "script/server")
|
90
|
+
(path + "script/server").chmod(744)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc "convert [directory]","Inject all partials, into all HTML files within directory"
|
95
|
+
method_options :partial_path => :optional, # Defaults to [directory]/../partials
|
96
|
+
:filter => :optional # What files should be converted defaults to *.html
|
97
|
+
def convert(path=".")
|
98
|
+
path,partial_path = template_paths(path,options["partial_path"])
|
99
|
+
filter = options["filter"] || "*.html"
|
100
|
+
puts "Converting #{filter} in #{path}"
|
101
|
+
puts " Taking partials from #{partial_path} (#{HtmlMockup::Template.partial_files(partial_path).size} found)"
|
102
|
+
|
103
|
+
if path.directory?
|
104
|
+
Dir.glob("#{path}/#{filter}").each do |file|
|
105
|
+
puts " Converting file: " + file
|
106
|
+
HtmlMockup::Template.open(file, :partial_path => partial_path).save
|
107
|
+
end
|
108
|
+
else
|
109
|
+
HtmlMockup::Template.open(path, :partial_path => partial_path).save
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
protected
|
116
|
+
|
117
|
+
def template_paths(path,partial_path=nil)
|
118
|
+
path = Pathname.new(path)
|
119
|
+
partial_path = partial_path && Pathname.new(partial_path) || (path + "../partials/").cleanpath
|
120
|
+
[path,partial_path]
|
121
|
+
end
|
122
|
+
|
123
|
+
def w3cvalidate(file)
|
124
|
+
validator = W3CValidator.new(File.read(file))
|
125
|
+
validator.validate!
|
126
|
+
if !options["show_valid"] && !validator.valid || options["show_valid"]
|
127
|
+
print "- #{file} "
|
128
|
+
print "(errors: #{validator.errors}, warnings: #{validator.warnings})\n"
|
129
|
+
end
|
130
|
+
validator.valid
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rack/request'
|
2
|
+
require 'rack/response'
|
3
|
+
require 'rack/file'
|
4
|
+
|
5
|
+
module HtmlMockup
|
6
|
+
module Rack
|
7
|
+
class HtmlMockup
|
8
|
+
def initialize(root,partial_path)
|
9
|
+
@docroot = root
|
10
|
+
@partial_path = partial_path
|
11
|
+
@file_server = ::Rack::File.new(@docroot)
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
path = env["PATH_INFO"]
|
16
|
+
|
17
|
+
# Append index.html/index.htm/index.rhtml if it's a diretory
|
18
|
+
if File.directory?(File.join(@docroot,path))
|
19
|
+
search_files = %w{.html .htm .rhtml}.map!{|p| File.join(@docroot,path,"index#{p}")}
|
20
|
+
# If it's already a .html/.htm/.rhtml file, render that file
|
21
|
+
elsif (path =~ /\.r?html?$/)
|
22
|
+
search_files = [File.join(@docroot,path)]
|
23
|
+
# If it ends with a slash or does not contain a . and it's not a directory
|
24
|
+
# try to add .html/.htm/.rhtml to see if that exists.
|
25
|
+
elsif (path =~ /\/$/) || (path =~ /^[^.]+$/)
|
26
|
+
search_files = [path + ".html", path + ".htm", path + ".rhtml"].map!{|p| File.join(@docroot,p) }
|
27
|
+
# Otherwise don't render anything at all.
|
28
|
+
else
|
29
|
+
search_files = []
|
30
|
+
end
|
31
|
+
|
32
|
+
if template_path = search_files.find{|p| File.exist?(p)}
|
33
|
+
env["rack.errors"].puts "Rendering template #{template_path.inspect} (#{path.inspect})"
|
34
|
+
templ = ::HtmlMockup::Template.open(template_path, :partial_path => @partial_path)
|
35
|
+
resp = ::Rack::Response.new do |res|
|
36
|
+
res.status = 200
|
37
|
+
res.write templ.render
|
38
|
+
end
|
39
|
+
resp.finish
|
40
|
+
else
|
41
|
+
env["rack.errors"].puts "Invoking file handler for #{path.inspect}"
|
42
|
+
@file_server.call(env)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rack/request'
|
2
|
+
require 'rack/response'
|
3
|
+
|
4
|
+
module HtmlMockup
|
5
|
+
module Rack
|
6
|
+
class HtmlValidator
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
resp = @app.call(env)
|
13
|
+
if resp[1]["Content-Type"].to_s.include?("html")
|
14
|
+
str = ""
|
15
|
+
resp[2].each{|c| str << c}
|
16
|
+
validator = W3CValidator.new(str)
|
17
|
+
validator.validate!
|
18
|
+
if !validator.valid
|
19
|
+
env["rack.errors"].puts "Validation failed on #{env["PATH_INFO"]}: (errors: #{validator.errors}, warnings: #{validator.warnings})"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
resp
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'strscan'
|
3
|
+
require 'erb'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module HtmlMockup
|
7
|
+
class Template
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def open(filename,options={})
|
11
|
+
raise "Unknown file #{filename}" unless File.exist?(filename)
|
12
|
+
self.new(File.read(filename),options.update(:target_file => filename))
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns all available partials in path
|
16
|
+
def partials(path)
|
17
|
+
available_partials = {}
|
18
|
+
path = Pathname.new(path)
|
19
|
+
self.partial_files(path).inject({}) do |mem,f|
|
20
|
+
name = f.to_s.split(".",2)[0]
|
21
|
+
mem[name] = (path + f).read
|
22
|
+
mem
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def partial_files(path)
|
27
|
+
filter = "*.part.?html"
|
28
|
+
files = []
|
29
|
+
Dir.chdir(Pathname.new(path)) do
|
30
|
+
files = Dir.glob(filter)
|
31
|
+
end
|
32
|
+
files
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create a new HtmlMockupTemplate
|
38
|
+
#
|
39
|
+
# ==== Parameters
|
40
|
+
# template<String>:: The template to parse
|
41
|
+
# options<Hash>:: See options
|
42
|
+
#
|
43
|
+
# ==== Options (optional)
|
44
|
+
# partial_path<String>:: Path where the partials reside (default: $0/../../partials)
|
45
|
+
#--
|
46
|
+
def initialize(template, options={})
|
47
|
+
defaults = {:partial_path => File.dirname(__FILE__) + "/../../partials/"}
|
48
|
+
@template = template
|
49
|
+
@options = defaults.update(options)
|
50
|
+
@scanner = StringScanner.new(@template)
|
51
|
+
raise "Partial path '#{self.options[:partial_path]}' not found" unless File.exist?(self.options[:partial_path])
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_reader :template, :options, :scanner
|
55
|
+
|
56
|
+
# Renders the template and returns it as a string
|
57
|
+
#
|
58
|
+
# ==== Returns
|
59
|
+
# String:: The rendered template
|
60
|
+
#--
|
61
|
+
def render
|
62
|
+
out = ""
|
63
|
+
while (partial = self.parse_partial_tag!) do
|
64
|
+
tag,params,scanned = partial
|
65
|
+
# add new skipped content to output file
|
66
|
+
out << scanned
|
67
|
+
|
68
|
+
# scan until end of tag
|
69
|
+
current_content = self.scanner.scan_until(/<!-- \[STOP:#{tag}\] -->/)
|
70
|
+
out << (render_partial(tag,params) || current_content)
|
71
|
+
end
|
72
|
+
out << scanner.rest
|
73
|
+
end
|
74
|
+
|
75
|
+
def save(filename=self.options[:target_file])
|
76
|
+
File.open(filename,"w"){|f| f.write render}
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
def available_partials(force=false)
|
82
|
+
return @_available_partials if @_available_partials && !force
|
83
|
+
@_available_partials = self.class.partials(self.options[:partial_path])
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_partial_tag!
|
87
|
+
params = {}
|
88
|
+
scanned = ""
|
89
|
+
begin_of_tag = self.scanner.scan_until(/<!-- \[START:/)
|
90
|
+
return nil unless begin_of_tag
|
91
|
+
scanned << begin_of_tag
|
92
|
+
scanned << tag = self.scanner.scan(/[a-z0-9_]+/)
|
93
|
+
if scanned_questionmark = self.scanner.scan(/\?/)
|
94
|
+
scanned << scanned_questionmark
|
95
|
+
scanned << raw_params = self.scanner.scan_until(/\] -->/)
|
96
|
+
raw_params.gsub!(/\] -->$/,"")
|
97
|
+
|
98
|
+
params = CGI.parse(raw_params)
|
99
|
+
params.keys.each{|k| params[k] = params[k].first }
|
100
|
+
else
|
101
|
+
scanned << self.scanner.scan_until(/\] -->/)
|
102
|
+
end
|
103
|
+
|
104
|
+
[tag,params,scanned]
|
105
|
+
end
|
106
|
+
|
107
|
+
def render_partial(tag,params)
|
108
|
+
return nil unless self.available_partials[tag]
|
109
|
+
template = ERB.new(self.available_partials[tag])
|
110
|
+
context = TemplateContext.new(params)
|
111
|
+
"\n" + template.result(context.get_binding).rstrip + "\n<!-- [STOP:#{tag}] -->"
|
112
|
+
end
|
113
|
+
|
114
|
+
class TemplateContext
|
115
|
+
def initialize(params)
|
116
|
+
params.each do |k,v|
|
117
|
+
self.instance_variable_set("@#{k}",v)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
def get_binding; binding(); end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module HtmlMockup
|
7
|
+
class W3CValidator
|
8
|
+
|
9
|
+
ValidationUri = "http://validator.w3.org/check"
|
10
|
+
|
11
|
+
attr_reader :valid,:response,:errors,:warnings,:status
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def validation_uri
|
15
|
+
@uri ||= URI.parse(ValidationUri)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(html)
|
20
|
+
@html = html
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate!
|
24
|
+
@status = @warnings = @errors = @response = @valid = nil
|
25
|
+
options = {"output" => "json"}
|
26
|
+
query,headers = build_post_query(options)
|
27
|
+
response = self.request(:post,self.class.validation_uri.path,query,headers)
|
28
|
+
@status,@warnings,@errors = response["x-w3c-validator-status"],response["x-w3c-validator-warnings"].to_i,response["x-w3c-validator-errors"].to_i
|
29
|
+
|
30
|
+
if @status == "Valid" && @warnings == 0 && @errors == 0
|
31
|
+
return @valid = true
|
32
|
+
else
|
33
|
+
begin
|
34
|
+
@response = YAML.load(response.body)
|
35
|
+
rescue
|
36
|
+
end
|
37
|
+
return (@valid = (@errros == 0))
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def build_post_query(options)
|
45
|
+
boundary = "validate-this-content-please"
|
46
|
+
headers = {"Content-type" => "multipart/form-data, boundary=" + boundary + " "}
|
47
|
+
|
48
|
+
parts = []
|
49
|
+
options.each do |k,v|
|
50
|
+
parts << post_param(k,v)
|
51
|
+
end
|
52
|
+
parts << file_param("uploaded_file","index.html",@html,"text/html")
|
53
|
+
|
54
|
+
q = parts.map{|p| "--#{boundary}\r\n#{p}"}.join("") + "--#{boundary}--"
|
55
|
+
[q,headers]
|
56
|
+
end
|
57
|
+
|
58
|
+
def post_param(k,v)
|
59
|
+
"Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
def file_param(k,filename,content,mime_type)
|
63
|
+
out = []
|
64
|
+
out << "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{filename}\""
|
65
|
+
out << "Content-Transfer-Encoding: binary"
|
66
|
+
out << "Content-Type: #{mime_type}"
|
67
|
+
out.join("\r\n") + "\r\n\r\n" + content + "\r\n"
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
# Makes request to remote service.
|
74
|
+
def request(method, path, *arguments)
|
75
|
+
result = nil
|
76
|
+
result = http.send(method, path, *arguments)
|
77
|
+
handle_response(result)
|
78
|
+
rescue Timeout::Error => e
|
79
|
+
raise
|
80
|
+
end
|
81
|
+
|
82
|
+
# Handles response and error codes from remote service.
|
83
|
+
def handle_response(response)
|
84
|
+
case response.code.to_i
|
85
|
+
when 301,302
|
86
|
+
raise "Redirect"
|
87
|
+
when 200...400
|
88
|
+
response
|
89
|
+
when 400
|
90
|
+
raise "Bad Request"
|
91
|
+
when 401
|
92
|
+
raise "Unauthorized Access"
|
93
|
+
when 403
|
94
|
+
raise "Forbidden Access"
|
95
|
+
when 404
|
96
|
+
raise "Rescoure not found"
|
97
|
+
when 405
|
98
|
+
raise "Method not allowed"
|
99
|
+
when 409
|
100
|
+
raise "Rescource conflict"
|
101
|
+
when 422
|
102
|
+
raise "Resource invalid"
|
103
|
+
when 401...500
|
104
|
+
raise "Client error"
|
105
|
+
when 500...600
|
106
|
+
raise "Server error"
|
107
|
+
else
|
108
|
+
raise "Unknown response: #{response.code.to_i}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def http
|
113
|
+
site = self.class.validation_uri
|
114
|
+
http = Net::HTTP.new(site.host, site.port)
|
115
|
+
# http.use_ssl = site.is_a?(URI::HTTPS)
|
116
|
+
# http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
|
117
|
+
http
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flurin-html_mockup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Flurin Egger
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-14 00:00:00 -07:00
|
13
|
+
default_executable: mockup
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thor
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.9
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rack
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.0
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: f.p.egger@gmail.com
|
37
|
+
executables:
|
38
|
+
- mockup
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- bin/mockup
|
45
|
+
- examples/html/green.gif
|
46
|
+
- examples/html/index.html
|
47
|
+
- examples/partials/test.part.rhtml
|
48
|
+
- examples/script/server
|
49
|
+
- lib/html_mockup/cli.rb
|
50
|
+
- lib/html_mockup/rack/html_mockup.rb
|
51
|
+
- lib/html_mockup/rack/html_validator.rb
|
52
|
+
- lib/html_mockup/template.rb
|
53
|
+
- lib/html_mockup/w3c_validator.rb
|
54
|
+
- README.rdoc
|
55
|
+
has_rdoc: false
|
56
|
+
homepage: http://github.com/flurin/html_mockup
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.2.0
|
78
|
+
signing_key:
|
79
|
+
specification_version: 2
|
80
|
+
summary: HTML Mockup is a set of tools to create self-containing HTML mockups.
|
81
|
+
test_files: []
|
82
|
+
|