html_mockup 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + "/../lib/html_mockup/cli"
4
+
5
+ HtmlMockup::Cli.start
@@ -0,0 +1,16 @@
1
+ require 'pathname'
2
+
3
+ begin
4
+ require File.dirname(__FILE__) + "/../vendor/html_mockup/lib/html_mockup/server"
5
+ rescue LoadError => e
6
+ require 'rubygems'
7
+ require 'html_mockup/server'
8
+ end
9
+
10
+ root_path = Pathname.new(File.dirname(__FILE__)) + "html"
11
+ partial_path = (root_path + "../partials/").realpath
12
+
13
+ mockup = HtmlMockup::Server.new(root_path,partial_path)
14
+
15
+ run mockup.application
16
+
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,3 @@
1
+ <div id="<%= @id || "fault" %>">
2
+ Think?
3
+ </div>
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ begin
6
+ require File.dirname(__FILE__) + "/../vendor/html_mockup/lib/html_mockup/server"
7
+ rescue LoadError => e
8
+ require 'rubygems'
9
+ require 'html_mockup/server'
10
+ end
11
+
12
+ root_path = Pathname.new(File.dirname(__FILE__)) + "../html"
13
+ partial_path = (root_path + "../partials/").realpath
14
+
15
+ mockup = HtmlMockup::Server.new(root_path,partial_path)
16
+
17
+ # Add some of your own middleware here.
18
+ # mockup.use Rack::CommonLogger
19
+
20
+ mockup.run
@@ -0,0 +1,178 @@
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 => :string, # Defaults to 9000
15
+ :partial_path => :string, # Defaults to [directory]/../partials
16
+ :validate => :boolean, # Automatically validate all HTML responses @ the w3c
17
+ :handler => :string # The handler to use (defaults to mongrel)
18
+ def serve(path=".")
19
+ require File.dirname(__FILE__) + '/server'
20
+
21
+ @path,@partial_path = template_paths(path,options["partial_path"])
22
+
23
+ server_options = {}
24
+ server_options[:Port] = options["port"] || "9000"
25
+
26
+ server = Server.new(@path,@partial_path,options,server_options)
27
+
28
+ puts "Running HtmlMockup with #{server.handler.inspect} on port #{server_options[:Port]}"
29
+ puts " Taking partials from #{@partial_path} (#{HtmlMockup::Template.partial_files(@partial_path).size} found)"
30
+
31
+ server.run
32
+ end
33
+
34
+ desc "validate [directory/file]", "Validates the file or all HTML in directory"
35
+ method_options :show_valid => :boolean, # Also print a line for each valid file
36
+ :filter => :string # What files should be found, defaults to [^_]*.html
37
+ def validate(path=".")
38
+ filter = options["filter"] || "[^_]*.html"
39
+
40
+ puts "Filtering on #{options["filter"]}" if options["filter"]
41
+
42
+ if File.directory?(path)
43
+ any_invalid = false
44
+
45
+ if (files = Dir.glob("#{path}/**/#{filter}")).any?
46
+ files.each do |file|
47
+ if !self.w3cvalidate(file)
48
+ any_invalid = true
49
+ end
50
+ end
51
+ if !any_invalid
52
+ puts "All files were considered valid"
53
+ end
54
+ else
55
+ puts "No files matched \"#{filter}\""
56
+ end
57
+ elsif File.readable?(path)
58
+ self.w3cvalidate(path)
59
+ else
60
+ puts "No such file/directory #{path}"
61
+ end
62
+ end
63
+
64
+ desc "generate [directory]","Create a new HTML mockup directory tree in directory"
65
+ def generate(path)
66
+ path = Pathname.new(path)
67
+ if path.directory?
68
+ puts "Directory #{path} already exists, please only use this to create new mockups"
69
+ else
70
+ example_path = Pathname.new(File.dirname(__FILE__) + "/../../examples")
71
+ path.mkpath
72
+ html_path = path + "html"
73
+ mkdir(html_path)
74
+ mkdir(html_path + "stylesheets")
75
+ mkdir(html_path + "images")
76
+ mkdir(html_path + "javascripts")
77
+
78
+ mkdir(path + "partials")
79
+
80
+ mkdir(path + "script")
81
+ cp(example_path + "script/server",path + "script/server")
82
+ cp(example_path + "config.ru",path + "config.ru")
83
+ (path + "script/server").chmod(0755)
84
+ end
85
+ end
86
+
87
+ desc "convert [directory]","Inject all partials, into all HTML files within directory"
88
+ method_options :partial_path => :string, # Defaults to [directory]/../partials
89
+ :filter => :string # What files should be converted defaults to **/*.html
90
+ def convert(path=".")
91
+ path,partial_path = template_paths(path,options["partial_path"])
92
+ filter = options["filter"] || "**/*.html"
93
+ puts "Converting #{filter} in #{path}"
94
+ puts " Taking partials from #{partial_path} (#{HtmlMockup::Template.partial_files(partial_path).size} found)"
95
+
96
+ if path.directory?
97
+ Dir.glob("#{path}/#{filter}").each do |file|
98
+ puts " Converting file: " + file
99
+ HtmlMockup::Template.open(file, :partial_path => partial_path).save
100
+ end
101
+ else
102
+ HtmlMockup::Template.open(path, :partial_path => partial_path).save
103
+ end
104
+
105
+ end
106
+
107
+ desc "extract [source_path] [target_path]", "Extract a fully relative html mockup into target_path. It will expand all absolute href's, src's and action's into relative links if they are absolute"
108
+ method_options :partial_path => :string, # Defaults to [directory]/../partials
109
+ :filter => :string # What files should be converted defaults to **/*.html
110
+ def extract(source_path=".",target_path="../out")
111
+ require 'hpricot'
112
+ source_path,target_path = Pathname.new(source_path),Pathname.new(target_path)
113
+ source_path,partial_path = template_paths(source_path,options["partial_path"])
114
+ filter = options["filter"] || "**/*.html"
115
+ raise "Target #{target_path} already exists, please choose a new directory to extract into" if target_path.exist?
116
+
117
+ mkdir_p(target_path)
118
+ target_path = target_path.realpath
119
+
120
+ # Copy source to target first, we'll overwrite the templates later on.
121
+ cp_r(source_path.children,target_path)
122
+
123
+ Dir.chdir(source_path) do
124
+ Dir.glob(filter).each do |file_name|
125
+ source = HtmlMockup::Template.open(file_name, :partial_path => partial_path).render
126
+ cur_dir = Pathname.new(file_name).dirname
127
+ up_to_root = File.join([".."] * (file_name.split("/").size - 1))
128
+ doc = Hpricot(source)
129
+ %w{src href action}.each do |attribute|
130
+ (doc/"*[@#{attribute}]").each do |tag|
131
+ next unless tag[attribute] =~ /\A\//
132
+ if true_file = resolve_path(cur_dir + up_to_root + tag[attribute].sub(/\A\//,""))
133
+ tag[attribute] = true_file.relative_path_from(cur_dir)
134
+ else
135
+ puts "Could not resolve link #{tag[attribute]} in #{file_name}"
136
+ end
137
+ end
138
+ end
139
+
140
+ File.open(target_path + file_name,"w"){|f| f.write(doc.to_original_html) }
141
+ end
142
+ end
143
+ end
144
+
145
+ protected
146
+
147
+ def template_paths(path,partial_path=nil)
148
+ path = Pathname.new(path)
149
+ partial_path = partial_path && Pathname.new(partial_path) || (path + "../partials/").realpath
150
+ [path,partial_path]
151
+ end
152
+
153
+ def w3cvalidate(file)
154
+ validator = W3CValidator.new(File.read(file))
155
+ validator.validate!
156
+ if !options["show_valid"] && !validator.valid || options["show_valid"]
157
+ print "- #{file} "
158
+ print "(errors: #{validator.errors}, warnings: #{validator.warnings})\n"
159
+ end
160
+ validator.valid
161
+ end
162
+
163
+ def resolve_path(path)
164
+ path = Pathname.new(path) unless path.kind_of?(Pathname)
165
+ # Append index.html/index.htm/index.rhtml if it's a diretory
166
+ if path.directory?
167
+ search_files = %w{.html .htm}.map!{|p| path + "index#{p}" }
168
+ # If it ends with a slash or does not contain a . and it's not a directory
169
+ # try to add .html/.htm/.rhtml to see if that exists.
170
+ elsif (path =~ /\/$/) || (path =~ /^[^.]+$/)
171
+ search_files = [path.to_s + ".html", path.to_s + ".htm"].map!{|p| Pathname.new(p) }
172
+ else
173
+ search_files = [path]
174
+ end
175
+ search_files.find{|p| p.exist? }
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,56 @@
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
+ begin
35
+ templ = ::HtmlMockup::Template.open(template_path, :partial_path => @partial_path)
36
+ resp = ::Rack::Response.new do |res|
37
+ res.status = 200
38
+ res.write templ.render
39
+ end
40
+ resp.finish
41
+ rescue StandardError => e
42
+ env["rack.errors"].puts " #{e.message}"
43
+ resp = ::Rack::Response.new do |res|
44
+ res.status = 500
45
+ res.write "An error occurred"
46
+ end
47
+ resp.finish
48
+ end
49
+ else
50
+ env["rack.errors"].puts "Invoking file handler for #{path.inspect}"
51
+ @file_server.call(env)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ 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,80 @@
1
+ require 'rack'
2
+ require File.dirname(__FILE__) + "/template"
3
+ require File.dirname(__FILE__) + "/w3c_validator"
4
+ require File.dirname(__FILE__) + "/rack/html_mockup"
5
+ require File.dirname(__FILE__) + "/rack/html_validator"
6
+
7
+ module HtmlMockup
8
+ class Server
9
+ attr_accessor :options,:server_options, :root, :partial_path
10
+
11
+ def initialize(root,partial_path,options={},server_options={})
12
+ @stack = ::Rack::Builder.new
13
+
14
+ @middleware = []
15
+ @root = root
16
+ @partial_path = partial_path
17
+ @options,@server_options = options,server_options
18
+ end
19
+
20
+ # Use the specified Rack middleware
21
+ def use(middleware, *args, &block)
22
+ @middleware << [middleware, args, block]
23
+ end
24
+
25
+ def handler
26
+ if self.options[:handler]
27
+ begin
28
+ @handler = ::Rack::Handler.get(self.options[:handler])
29
+ rescue LoadError
30
+ rescue NameError
31
+ end
32
+ if @handler.nil?
33
+ puts "Handler '#{self.options[:handler]}' not found, using fallback."
34
+ end
35
+ end
36
+ @handler ||= detect_rack_handler
37
+ end
38
+
39
+ def run
40
+ self.handler.run self.application, @server_options do |server|
41
+ trap(:INT) do
42
+ ## Use thins' hard #stop! if available, otherwise just #stop
43
+ server.respond_to?(:stop!) ? server.stop! : server.stop
44
+ puts "Bby HtmlMockup"
45
+ end
46
+ end
47
+ end
48
+
49
+ def application
50
+ return @app if @app
51
+ @stack.use ::Rack::ShowExceptions
52
+ @stack.use ::Rack::Lint
53
+ @stack.use ::Rack::ConditionalGet
54
+
55
+ @middleware.each { |c,a,b| @stack.use(c, *a, &b) }
56
+
57
+ @stack.use Rack::HtmlValidator if self.options["validate"]
58
+ @stack.run Rack::HtmlMockup.new(self.root, self.partial_path)
59
+
60
+ @app = @stack.to_app
61
+ end
62
+
63
+
64
+ protected
65
+
66
+ # Sinatra's detect_rack_handler
67
+ def detect_rack_handler
68
+ servers = %w[mongrel thin webrick]
69
+ servers.each do |server_name|
70
+ begin
71
+ return ::Rack::Handler.get(server_name)
72
+ rescue LoadError
73
+ rescue NameError
74
+ end
75
+ end
76
+ raise "Server handler (#{servers.join(',')}) not found."
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,129 @@
1
+ require 'pathname'
2
+ require 'strscan'
3
+ require 'erb'
4
+ require 'cgi'
5
+
6
+ module HtmlMockup
7
+
8
+ class MissingPartial < StandardError; end
9
+
10
+ class Template
11
+
12
+ class << self
13
+ def open(filename,options={})
14
+ raise "Unknown file #{filename}" unless File.exist?(filename)
15
+ self.new(File.read(filename),options.update(:target_file => filename))
16
+ end
17
+
18
+ # Returns all available partials in path
19
+ def partials(path)
20
+ available_partials = {}
21
+ path = Pathname.new(path)
22
+ self.partial_files(path).inject({}) do |mem,f|
23
+ name = f.to_s.split(".",2)[0]
24
+ mem[name] = (path + f).read
25
+ mem
26
+ end
27
+ end
28
+
29
+ def partial_files(path)
30
+ filter = "*.part.{?h,h}tml"
31
+ files = []
32
+ Dir.chdir(Pathname.new(path)) do
33
+ files = Dir.glob(filter)
34
+ end
35
+ files
36
+ end
37
+
38
+ end
39
+
40
+ # Create a new HtmlMockupTemplate
41
+ #
42
+ # ==== Parameters
43
+ # template<String>:: The template to parse
44
+ # options<Hash>:: See options
45
+ #
46
+ # ==== Options (optional)
47
+ # partial_path<String>:: Path where the partials reside (default: $0/../../partials)
48
+ #--
49
+ def initialize(template, options={})
50
+ defaults = {:partial_path => File.dirname(__FILE__) + "/../../partials/"}
51
+ @template = template
52
+ @options = defaults.update(options)
53
+ @scanner = StringScanner.new(@template)
54
+ raise "Partial path '#{self.options[:partial_path]}' not found" unless File.exist?(self.options[:partial_path])
55
+ end
56
+
57
+ attr_reader :template, :options, :scanner
58
+
59
+ # Renders the template and returns it as a string
60
+ #
61
+ # ==== Returns
62
+ # String:: The rendered template
63
+ #--
64
+ def render
65
+ out = ""
66
+ while (partial = self.parse_partial_tag!) do
67
+ tag,params,scanned = partial
68
+ # add new skipped content to output file
69
+ out << scanned
70
+
71
+ # scan until end of tag
72
+ current_content = self.scanner.scan_until(/<!-- \[STOP:#{tag}\] -->/)
73
+ out << (render_partial(tag,params) || current_content)
74
+ end
75
+ out << scanner.rest
76
+ end
77
+
78
+ def save(filename=self.options[:target_file])
79
+ File.open(filename,"w"){|f| f.write render}
80
+ end
81
+
82
+ protected
83
+
84
+ def available_partials(force=false)
85
+ return @_available_partials if @_available_partials && !force
86
+ @_available_partials = self.class.partials(self.options[:partial_path])
87
+ end
88
+
89
+ def parse_partial_tag!
90
+ params = {}
91
+ scanned = ""
92
+ begin_of_tag = self.scanner.scan_until(/<!-- \[START:/)
93
+ return nil unless begin_of_tag
94
+ scanned << begin_of_tag
95
+ scanned << tag = self.scanner.scan(/[a-z0-9_]+/)
96
+ if scanned_questionmark = self.scanner.scan(/\?/)
97
+ scanned << scanned_questionmark
98
+ scanned << raw_params = self.scanner.scan_until(/\] -->/)
99
+ raw_params.gsub!(/\] -->$/,"")
100
+
101
+ params = CGI.parse(raw_params)
102
+ params.keys.each{|k| params[k] = params[k].first }
103
+ else
104
+ scanned << self.scanner.scan_until(/\] -->/)
105
+ end
106
+
107
+ [tag,params,scanned]
108
+ end
109
+
110
+ def render_partial(tag,params)
111
+ unless self.available_partials[tag]
112
+ raise MissingPartial.new("Could not find partial '#{tag}' in partial path '#{@options[:partial_path]}'")
113
+ end
114
+ template = ERB.new(self.available_partials[tag])
115
+ context = TemplateContext.new(params)
116
+ "\n" + template.result(context.get_binding).rstrip + "\n<!-- [STOP:#{tag}] -->"
117
+ end
118
+
119
+ class TemplateContext
120
+ def initialize(params)
121
+ params.each do |k,v|
122
+ self.instance_variable_set("@#{k}",v)
123
+ end
124
+ end
125
+ def get_binding; binding(); end
126
+ end
127
+
128
+ end
129
+ 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,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: html_mockup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Flurin Egger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-18 00:00:00 +01: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.12.0
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: 1.0.0
34
+ version:
35
+ description:
36
+ email: flurin@digitpaint.nl
37
+ executables:
38
+ - mockup
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.rdoc
43
+ files:
44
+ - bin/mockup
45
+ - examples/config.ru
46
+ - examples/html/green.gif
47
+ - examples/html/index.html
48
+ - examples/partials/test.part.rhtml
49
+ - examples/script/server
50
+ - lib/html_mockup/cli.rb
51
+ - lib/html_mockup/rack/html_mockup.rb
52
+ - lib/html_mockup/rack/html_validator.rb
53
+ - lib/html_mockup/server.rb
54
+ - lib/html_mockup/template.rb
55
+ - lib/html_mockup/w3c_validator.rb
56
+ - README.rdoc
57
+ has_rdoc: true
58
+ homepage: http://github.com/flurin/html_mockup
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --charset=UTF-8
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.3.5
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: HTML Mockup is a set of tools to create self-containing HTML mockups.
85
+ test_files: []
86
+