utopia 0.9.31 → 0.9.32

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/bin/utopia ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'utopia/setup'
5
+ require 'rake'
6
+
7
+ $app = Rake.application = Rake::Application.new
8
+ $app.init('Utopia')
9
+
10
+ task :setup do
11
+ Utopia::Setup.copy(Dir.getwd)
12
+
13
+ if `which thin`.strip == ""
14
+ $stderr.puts "Next, please install thin: `sudo gem install thin'."
15
+ $stderr.puts "Once you've done that, type `thin start' to start the web server."
16
+ else
17
+ $stderr.puts "Type `thin start' to start the web server."
18
+ end
19
+
20
+ if `which git`.strip == ""
21
+ $stderr.puts "Now is a good time to learn about git : http://git-scm.com/"
22
+ end
23
+
24
+ unless File.exist? '.git'
25
+ $stderr.puts "I recommend using git for version control."
26
+ end
27
+
28
+ $stderr.puts "*** Thanks for trying out Utopia! ***"
29
+ end
30
+
31
+ task :default => :setup
32
+
33
+ $app.top_level
@@ -0,0 +1,25 @@
1
+ # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
+ # Copyright 2010 Samuel Williams. All rights reserved.
3
+ # See <utopia.rb> for licensing details.
4
+
5
+ class Array
6
+ def find_index(&block)
7
+ each_with_index do |item, index|
8
+ if yield(item)
9
+ return index
10
+ end
11
+ end
12
+
13
+ return nil
14
+ end
15
+
16
+ def split_at(&block)
17
+ index = find_index(&block)
18
+
19
+ if index
20
+ return [self[0...index], self[index], self[index+1..-1]]
21
+ end
22
+
23
+ return [[], nil, []]
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
+ # Copyright 2010 Samuel Williams. All rights reserved.
3
+ # See <utopia.rb> for licensing details.
4
+
5
+ require 'active_support'
6
+
7
+ class Date
8
+ alias_method :old_cmp, :<=>
9
+
10
+ def <=> (other)
11
+ # Comparing a Date with something that has a time component truncates the time
12
+ # component, thus we need to check if the other object has a more exact comparison
13
+ # function.
14
+ if other.respond_to?(:hour)
15
+ return (other <=> self) * -1
16
+ else
17
+ old_cmp(other)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
+ # Copyright 2010 Samuel Williams. All rights reserved.
3
+ # See <utopia.rb> for licensing details.
4
+
5
+ class Hash
6
+ def symbolize_keys
7
+ inject({}) do |options, (key, value)|
8
+ options[(key.to_sym rescue key) || key] = value
9
+ options
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
+ # Copyright 2010 Samuel Williams. All rights reserved.
3
+ # See <utopia.rb> for licensing details.
4
+
5
+ class Rack::Response
6
+ def do_not_cache!
7
+ self["Cache-Control"] = "no-cache, must-revalidate"
8
+ self["Expires"] = Time.now.httpdate
9
+ end
10
+
11
+ def cache!(duration = 3600)
12
+ self["Cache-Control"] = "public, max-age=#{duration}"
13
+ self["Expires"] = (Time.now + duration).httpdate
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
+ # Copyright 2010 Samuel Williams. All rights reserved.
3
+ # See <utopia.rb> for licensing details.
4
+
5
+ class Regexp
6
+ def self.starts_with(string)
7
+ return /^#{Regexp.escape(string)}/
8
+ end
9
+
10
+ def self.ends_with(string)
11
+ return /#{Regexp.escape(string)}$/
12
+ end
13
+
14
+ def self.contains(string)
15
+ return Regexp.new(string)
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
+ # Copyright 2010 Samuel Williams. All rights reserved.
3
+ # See <utopia.rb> for licensing details.
4
+
5
+ class String
6
+ HTML_ESCAPE = {"&" => "&amp;", "<" => "&lt;", ">" => "&gt;", "\"" => "&quot;"}
7
+ HTML_ESCAPE_PATTERN = Regexp.new("[" + Regexp.quote(HTML_ESCAPE.keys.join) + "]")
8
+
9
+ def to_html
10
+ gsub(HTML_ESCAPE_PATTERN){|c| HTML_ESCAPE[c]}
11
+ end
12
+
13
+ def to_title
14
+ (" " + self).gsub(/[ \-_](.)/){" " + $1.upcase}.strip
15
+ end
16
+
17
+ def to_snake
18
+ self.gsub("::", "").gsub(/([A-Z]+)/){"_" + $1.downcase}.sub(/^_+/, "")
19
+ end
20
+ end
data/lib/utopia/link.rb CHANGED
@@ -2,7 +2,10 @@
2
2
  # Copyright 2010 Samuel Williams. All rights reserved.
3
3
  # See <utopia.rb> for licensing details.
4
4
 
5
- require 'utopia/extensions'
5
+ require 'utopia/extensions/date'
6
+ require 'utopia/extensions/string'
7
+ require 'utopia/extensions/hash'
8
+ require 'utopia/extensions/array'
6
9
 
7
10
  module Utopia
8
11
 
@@ -132,7 +135,7 @@ module Utopia
132
135
  :virtual => true,
133
136
  :indices => false,
134
137
  :sort => :order,
135
- :hidden => :hidden,
138
+ :display => :display,
136
139
  :locale => nil
137
140
  }
138
141
 
@@ -196,8 +199,8 @@ module Utopia
196
199
  end
197
200
  end
198
201
 
199
- if options[:hidden]
200
- links = links.delete_if{|link| link[options[:hidden]]}
202
+ if options[:display]
203
+ links = links.delete_if{|link| link[options[:display]] == false}
201
204
  end
202
205
 
203
206
  if options[:name]
@@ -5,6 +5,8 @@
5
5
  require 'pathname'
6
6
  require 'logger'
7
7
 
8
+ require 'utopia/extensions/rack'
9
+
8
10
  module Utopia
9
11
  LOG = Logger.new($stderr)
10
12
  LOG.level = Logger::DEBUG
@@ -16,7 +18,6 @@ module Utopia
16
18
  end
17
19
  end
18
20
 
19
- require 'utopia/extensions'
20
21
  require 'utopia/path'
21
22
  require 'utopia/tag'
22
23
 
@@ -19,7 +19,7 @@ module Utopia
19
19
 
20
20
  @root = File.expand_path(options[:root] || Utopia::Middleware::default_root)
21
21
 
22
- LOG.info "#{self.class.name}: Running in #{@root}"
22
+ LOG.info "** #{self.class.name}: Running in #{@root}"
23
23
 
24
24
  # Set to hash to enable caching
25
25
  @nodes = {}
@@ -142,7 +142,7 @@ module Utopia
142
142
  @app = app
143
143
  @root = options[:root] || Utopia::Middleware::default_root
144
144
 
145
- LOG.info "#{self.class.name}: Running in #{@root}"
145
+ LOG.info "** #{self.class.name}: Running in #{@root}"
146
146
 
147
147
  @controllers = {}
148
148
  @cache_controllers = (UTOPIA_ENV == :production)
@@ -36,6 +36,10 @@ module Utopia
36
36
  end
37
37
 
38
38
  @log << record
39
+
40
+ if UTOPIA_ENV != :production
41
+ $stderr.puts ">> #{record[:method]} #{record[:url]} -> #{response[0]}"
42
+ end
39
43
  end
40
44
 
41
45
  def initialize(app, options = {})
@@ -3,6 +3,8 @@
3
3
  # See <utopia.rb> for licensing details.
4
4
 
5
5
  require 'utopia/middleware'
6
+ require 'utopia/extensions/regexp'
7
+ require 'utopia/extensions/string'
6
8
 
7
9
  module Utopia
8
10
  module Middleware
@@ -112,7 +114,7 @@ module Utopia
112
114
 
113
115
  @errors = options[:errors]
114
116
 
115
- LOG.info "#{self.class.name}: Running with #{@strings.size + @patterns.size} rules"
117
+ LOG.info "** #{self.class.name}: Running with #{@strings.size + @patterns.size} rules"
116
118
  end
117
119
 
118
120
  def redirect(uri, match_data)
@@ -13,12 +13,34 @@ module Utopia
13
13
  module Middleware
14
14
 
15
15
  class Static
16
- DEFAULT_TYPES = [
17
- "html", "css", "js", "txt", "rtf", "xml",
18
- "pdf", "zip", "tar", "tgz", "tar.gz", "tar.bz2", "dmg",
19
- "mp3", "mp4", "wav", "aiff", ["aac", "audio/x-aac"], "mov", "avi", "wmv",
20
- /^image/
21
- ]
16
+ MIME_TYPES = {
17
+ :xiph => {
18
+ "ogx" => "application/ogg",
19
+ "ogv" => "video/ogg",
20
+ "oga" => "audio/ogg",
21
+ "ogg" => "audio/ogg",
22
+ "spx" => "audio/ogg",
23
+ "flac" => "audio/flac",
24
+ "anx" => "application/annodex",
25
+ "axa" => "audio/annodex",
26
+ "xspf" => "application/xspf+xml",
27
+ },
28
+ :media => [
29
+ :xiph, "mp3", "mp4", "wav", "aiff", ["aac", "audio/x-aac"], "mov", "avi", "wmv", "mpg"
30
+ ],
31
+ :text => [
32
+ "html", "css", "js", "txt", "rtf", "xml", "pdf"
33
+ ],
34
+ :archive => [
35
+ "zip", "tar", "tgz", "tar.gz", "tar.bz2", ["dmg", "application/x-apple-diskimage"]
36
+ ],
37
+ :images => [
38
+ "png", "gif", "jpeg", "tiff"
39
+ ],
40
+ :default => [
41
+ :media, :text, :archive, :images
42
+ ]
43
+ }
22
44
 
23
45
  private
24
46
 
@@ -69,16 +91,18 @@ module Utopia
69
91
  result = {}
70
92
 
71
93
  extract_extensions = lambda do |mime_type|
94
+ # LOG.info "Extracting #{mime_type.inspect}"
72
95
  mime_type.extensions.each{|ext| result["." + ext] = mime_type.content_type}
73
96
  end
74
97
 
75
98
  types.each do |type|
76
99
  current_count = result.size
100
+ # LOG.info "Processing #{type.inspect}"
77
101
 
78
102
  begin
79
103
  case type
80
- when :defaults
81
- result = load_mime_types(DEFAULT_TYPES).merge(result)
104
+ when Symbol
105
+ result = load_mime_types(MIME_TYPES[type]).merge(result)
82
106
  when Array
83
107
  result["." + type[0]] = type[1]
84
108
  when String
@@ -98,7 +122,7 @@ module Utopia
98
122
  end
99
123
 
100
124
  if result.size == current_count
101
- LOG.warn "#{self.class.name}: Could not find any mime type for file extension #{type.inspect}"
125
+ LOG.warn "#{self.class.name}: Could not find any mime type for #{type.inspect}"
102
126
  end
103
127
  end
104
128
 
@@ -113,12 +137,13 @@ module Utopia
113
137
  if options[:types]
114
138
  @extensions = load_mime_types(options[:types])
115
139
  else
116
- @extensions = load_mime_types(DEFAULT_TYPES)
140
+ @extensions = load_mime_types(MIME_TYPES[:default])
117
141
  end
118
142
 
119
143
  @cache_control = options[:cache_control] || "public, max-age=3600"
120
144
 
121
- LOG.info "#{self.class.name}: Running in #{@root} with #{extensions.size} filetypes"
145
+ LOG.info "** #{self.class.name}: Running in #{@root} with #{extensions.size} filetypes"
146
+ # LOG.info @extensions.inspect
122
147
  end
123
148
 
124
149
  def fetch_file(path)
@@ -0,0 +1,39 @@
1
+
2
+ require 'utopia/version'
3
+ require 'fileutils'
4
+ require 'find'
5
+ require 'rake'
6
+
7
+ module Utopia
8
+ module Setup
9
+ ROOT = File.join(File.dirname(__FILE__), "setup", "")
10
+ DIRECTORIES = ["access_log", "cache", "cache/meta", "cache/head", "lib", "pages", "public"]
11
+
12
+ def self.copy(to, config = {})
13
+ $stderr.puts "Copying files from #{ROOT} to #{to}..."
14
+ Find.find(ROOT) do |src|
15
+ dst = File.join(to, src[ROOT.size..-1])
16
+
17
+ if File.directory?(src)
18
+ FileUtils.mkdir_p(dst)
19
+ else
20
+ if File.exist? dst
21
+ $stderr.puts "File already exists: #{dst}!"
22
+ else
23
+ $stderr.puts "Copying #{src} to #{dst}..."
24
+ FileUtils.cp(src, dst)
25
+ end
26
+ end
27
+ end
28
+
29
+ DIRECTORIES.each do |path|
30
+ FileUtils.mkdir_p(File.join(to, path))
31
+ end
32
+
33
+ $stderr.puts "Updating config.ru..."
34
+ config_ru = File.join(to, "config.ru")
35
+ buf = File.read(config_ru).gsub('$UTOPIA_VERSION', Utopia::VERSION::STRING.dump)
36
+ File.open(config_ru, "w") { |fp| fp.write(buf) }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env rackup
2
+
3
+ UTOPIA_ENV = (ENV['UTOPIA_ENV'] || ENV['RACK_ENV'] || :development).to_sym
4
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "lib")
5
+
6
+ # It is recommended that you always explicity specify the version of the gem you are using.
7
+ gem 'utopia', $UTOPIA_VERSION
8
+ require 'utopia/middleware/all'
9
+ require 'utopia/tags/env'
10
+
11
+ gem 'rack-contrib'
12
+ require 'rack/contrib'
13
+
14
+ # Utopia relies heavily on accurately caching resources
15
+ gem 'rack-cache'
16
+ require 'rack/cache'
17
+
18
+ if UTOPIA_ENV == :development
19
+ use Rack::ShowExceptions
20
+ else
21
+ use Utopia::Middleware::ExceptionHandler, "/errors/exception"
22
+
23
+ # Fill out these details to receive email reports of exceptions when running in a production environment.
24
+ # use Rack::MailExceptions do |mail|
25
+ # mail.from $MAIL_EXCEPTIONS_FROM
26
+ # mail.to $MAIL_EXCEPTIONS_TO
27
+ # mail.subject "Website Error: %s"
28
+ # end
29
+ end
30
+
31
+ use Rack::ContentLength
32
+ use Utopia::Middleware::Logger
33
+
34
+ use Utopia::Middleware::Redirector, {
35
+ :strings => {
36
+ '/' => '/welcome/index',
37
+ '/utopia' => 'http://www.oriontransfer.co.nz/software/utopia/demo'
38
+ },
39
+ :errors => {
40
+ 404 => "/errors/file-not-found"
41
+ }
42
+ }
43
+
44
+ use Utopia::Middleware::Requester
45
+ use Utopia::Middleware::DirectoryIndex
46
+ use Utopia::Middleware::Controller
47
+ use Utopia::Middleware::Static
48
+
49
+ if UTOPIA_ENV == :production
50
+ use Rack::Cache, {
51
+ :metastore => "file:#{Utopia::Middleware::default_root("cache/meta")}",
52
+ :entitystore => "file:#{Utopia::Middleware::default_root("cache/body")}",
53
+ :verbose => false
54
+ }
55
+ end
56
+
57
+ use Utopia::Middleware::Content
58
+
59
+ run lambda { [404, {}, []] }
@@ -0,0 +1 @@
1
+ You can add additional code for your application in this directory, and require it directly from the config.ru.
@@ -0,0 +1,2 @@
1
+ <?r @title ||= content ?>
2
+ <h1><content/></h1>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <?r response["Content-Type"] = "text/html; charset=utf-8" ?>
5
+ <?r response["Cache-Control"] = "max-age=3600" ?>
6
+
7
+ <?r if title = (attributes["title"] || @title) ?>
8
+ <title>#{title.gsub(/<.*?>/, "")} - Utopia</title>
9
+ <?r else ?>
10
+ <title>Utopia</title>
11
+ <?r end ?>
12
+
13
+ <link rel="icon" type="image/png" href="/_static/icon.png" />
14
+ <link rel="stylesheet" href="/_static/site.css" type="text/css" media="screen" charset="utf-8" />
15
+ </head>
16
+
17
+ <body class="ledlighting">
18
+ <div id="header">
19
+ </div>
20
+
21
+ <div id="page">
22
+ <content />
23
+ </div>
24
+ </body>
25
+ </html>
@@ -0,0 +1,51 @@
1
+ /* Copyright (c) 2010 Orion Transfer Ltd. All Rights Reserved. */
2
+
3
+ body, p, ol, ul, blockquote {
4
+ font-family: "Skia", verdana, arial, helvetica, sans-serif;
5
+ line-height: 18px;
6
+
7
+ color: #339;
8
+ }
9
+
10
+ h1, h2, h3, h4, h5, h6 {
11
+ font-family: menlo, monospace;
12
+ color: #303;
13
+
14
+ margin-top: 2em;
15
+ margin-bottom: 1em;
16
+ }
17
+
18
+ body {
19
+ background: url(/_static/background.png) #fff center no-repeat fixed;
20
+ padding: 50px;
21
+ }
22
+
23
+ img {
24
+ border: none;
25
+ }
26
+
27
+ a {
28
+ color: #33a;
29
+ }
30
+
31
+ a:hover {
32
+ color: #55c;
33
+ }
34
+
35
+ p, dl, h3 {
36
+ line-height: 1.4em;
37
+ margin: 1em;
38
+ }
39
+
40
+ h3 {
41
+ border-bottom: 1px solid #ccf;
42
+ }
43
+
44
+ ul {
45
+ line-height: 1.4em;
46
+ margin-bottom: 1em;
47
+ }
48
+
49
+ h3, h4, h5, h6 {
50
+ font-weight: normal;
51
+ }
@@ -0,0 +1,5 @@
1
+ <page>
2
+ <heading>Exception</heading>
3
+
4
+ <p>It seems like something didn't quite work out as expected!</p>
5
+ </page>
@@ -0,0 +1,5 @@
1
+ <page>
2
+ <heading>File Not Found</heading>
3
+
4
+ <p>The file you requested is unfortunately not available at this time!</p>
5
+ </page>
@@ -0,0 +1,2 @@
1
+ errors:
2
+ display: false
@@ -0,0 +1,7 @@
1
+ <page>
2
+ <heading>Welcome to Utopia</heading>
3
+
4
+ <p>Utopia is designed to simply your life. It is not an application development framework. It is not a content management system. It does not require a database. It isn't model view controller. It is simply a platform on which websites can be easily developed with a minimum of effort.</p>
5
+
6
+ <p><a href="http://www.oriontransfer.co.nz/utopia/setup">Utopia Project Page &amp; Documentation</a></p>
7
+ </page>
@@ -0,0 +1 @@
1
+ This directory is required by Apache/Phusion Passenger.
@@ -3,10 +3,10 @@
3
3
  # See <utopia.rb> for licensing details.
4
4
 
5
5
  module Utopia
6
- module VERSION #:nodoc:
6
+ module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 9
9
- TINY = 31
9
+ TINY = 32
10
10
 
11
11
  STRING = [MAJOR, MINOR, TINY].join('.')
12
12
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 9
8
- - 31
9
- version: 0.9.31
8
+ - 32
9
+ version: 0.9.32
10
10
  platform: ruby
11
11
  authors:
12
12
  - Samuel Williams
@@ -14,8 +14,8 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-16 00:00:00 +12:00
18
- default_executable:
17
+ date: 2010-05-19 00:00:00 +12:00
18
+ default_executable: utopia
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: mime-types
@@ -91,8 +91,8 @@ dependencies:
91
91
  version_requirements: *id006
92
92
  description:
93
93
  email: samuel.williams@oriontransfer.co.nz
94
- executables: []
95
-
94
+ executables:
95
+ - utopia
96
96
  extensions: []
97
97
 
98
98
  extra_rdoc_files: []
@@ -101,7 +101,12 @@ files:
101
101
  - ext/utopia/xnode/fast_scanner/extconf.rb
102
102
  - ext/utopia/xnode/fast_scanner/parser.c
103
103
  - lib/utopia/etanni.rb
104
- - lib/utopia/extensions.rb
104
+ - lib/utopia/extensions/array.rb
105
+ - lib/utopia/extensions/date.rb
106
+ - lib/utopia/extensions/hash.rb
107
+ - lib/utopia/extensions/rack.rb
108
+ - lib/utopia/extensions/regexp.rb
109
+ - lib/utopia/extensions/string.rb
105
110
  - lib/utopia/http_status_codes.rb
106
111
  - lib/utopia/link.rb
107
112
  - lib/utopia/middleware/all.rb
@@ -119,6 +124,19 @@ files:
119
124
  - lib/utopia/middleware.rb
120
125
  - lib/utopia/path.rb
121
126
  - lib/utopia/session/encrypted_cookie.rb
127
+ - lib/utopia/setup/config.ru
128
+ - lib/utopia/setup/lib/readme.txt
129
+ - lib/utopia/setup/pages/_heading.xnode
130
+ - lib/utopia/setup/pages/_page.xnode
131
+ - lib/utopia/setup/pages/_static/background.png
132
+ - lib/utopia/setup/pages/_static/icon.png
133
+ - lib/utopia/setup/pages/_static/site.css
134
+ - lib/utopia/setup/pages/errors/exception.xnode
135
+ - lib/utopia/setup/pages/errors/file-not-found.xnode
136
+ - lib/utopia/setup/pages/links.yaml
137
+ - lib/utopia/setup/pages/welcome/index.xnode
138
+ - lib/utopia/setup/public/readme.txt
139
+ - lib/utopia/setup.rb
122
140
  - lib/utopia/tag.rb
123
141
  - lib/utopia/tags/all.rb
124
142
  - lib/utopia/tags/env.rb
@@ -134,6 +152,7 @@ files:
134
152
  - lib/utopia/xnode/scanner.rb
135
153
  - lib/utopia/xnode.rb
136
154
  - lib/utopia.rb
155
+ - bin/utopia
137
156
  has_rdoc: true
138
157
  homepage: http://www.oriontransfer.co.nz/software/utopia
139
158
  licenses: []
@@ -1,90 +0,0 @@
1
- # This file is part of the "Utopia Framework" project, and is licensed under the GNU AGPLv3.
2
- # Copyright 2010 Samuel Williams. All rights reserved.
3
- # See <utopia.rb> for licensing details.
4
-
5
- require 'active_support'
6
-
7
- class Date
8
- alias_method :old_cmp, :<=>
9
-
10
- def <=> (other)
11
- # Comparing a Date with something that has a time component truncates the time
12
- # component, thus we need to check if the other object has a more exact comparison
13
- # function.
14
- if other.respond_to?(:hour)
15
- return (other <=> self) * -1
16
- else
17
- old_cmp(other)
18
- end
19
- end
20
- end
21
-
22
- class Regexp
23
- def self.starts_with(string)
24
- return /^#{Regexp.escape(string)}/
25
- end
26
-
27
- def self.ends_with(string)
28
- return /#{Regexp.escape(string)}$/
29
- end
30
-
31
- def self.contains(string)
32
- return Regexp.new(string)
33
- end
34
- end
35
-
36
- class String
37
- HTML_ESCAPE = {"&" => "&amp;", "<" => "&lt;", ">" => "&gt;", "\"" => "&quot;"}
38
- HTML_ESCAPE_PATTERN = Regexp.new("[" + Regexp.quote(HTML_ESCAPE.keys.join) + "]")
39
-
40
- def to_html
41
- gsub(HTML_ESCAPE_PATTERN){|c| HTML_ESCAPE[c]}
42
- end
43
-
44
- def to_title
45
- (" " + self).gsub(/[ \-_](.)/){" " + $1.upcase}.strip
46
- end
47
-
48
- def to_snake
49
- self.gsub("::", "").gsub(/([A-Z]+)/){"_" + $1.downcase}.sub(/^_+/, "")
50
- end
51
- end
52
-
53
- class Hash
54
- def symbolize_keys
55
- inject({}) do |options, (key, value)|
56
- options[(key.to_sym rescue key) || key] = value
57
- options
58
- end
59
- end
60
- end
61
-
62
- class Array
63
- def find_index(&block)
64
- each_with_index do |item, index|
65
- if yield(item)
66
- return index
67
- end
68
- end
69
-
70
- return nil
71
- end
72
-
73
- def split_at(&block)
74
- index = find_index(&block)
75
-
76
- if index
77
- return [self[0...index], self[index], self[index+1..-1]]
78
- end
79
-
80
- return [[], nil, []]
81
- end
82
- end
83
-
84
- if defined? Rack
85
- class Rack::Request
86
- def self.new(*args)
87
- super(*args)
88
- end
89
- end
90
- end