piano 0.10.4 → 0.10.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +248 -234
- data/Rakefile +1 -1
- data/bin/piano +62 -87
- data/bin/piano~ +87 -0
- data/lib/piano.rb +46 -186
- data/lib/piano/controllerloader.rb +39 -39
- data/lib/piano/routes.rb +23 -23
- data/lib/piano/version.rb +3 -3
- data/lib/sinatra/piano.rb +141 -0
- data/sample/data/index.yaml +7 -7
- data/sample/index.haml +10 -10
- data/sample/style.sass +5 -5
- metadata +22 -21
- data/Gemfile +0 -4
- data/spec/controller_spec.rb +0 -90
data/Rakefile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'bundler'
|
2
|
-
Bundler::GemHelper.install_tasks
|
2
|
+
Bundler::GemHelper.install_tasks
|
data/bin/piano
CHANGED
@@ -1,87 +1,62 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require "
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
self.extend Metafun::Delegator
|
64
|
-
self.delegate Piano::Base, :get, :patch, :put, :post, :delete,
|
65
|
-
:head, :options, :template, :layout,
|
66
|
-
:before, :after, :error, :not_found,
|
67
|
-
:configure, :set, :mime_type, :enable,
|
68
|
-
:disable, :use, :development?, :test?,
|
69
|
-
:production?, :helpers, :settings
|
70
|
-
|
71
|
-
self.helpers Sinatra::Piano
|
72
|
-
|
73
|
-
$LOAD_PATH << Dir.pwd
|
74
|
-
|
75
|
-
if File.exists?(File.expand_path(Dir.pwd) + "/Pianofile")
|
76
|
-
puts "Pianofile found, loading..."
|
77
|
-
load File.expand_path(Dir.pwd) + "/Pianofile"
|
78
|
-
end
|
79
|
-
|
80
|
-
if File.exist?("controllers") && File.directory?("controllers")
|
81
|
-
puts "'controllers' directory found, loading '.controller' files"
|
82
|
-
Piano::ControllerLoader.folder "controllers"
|
83
|
-
end
|
84
|
-
|
85
|
-
require "piano/routes"
|
86
|
-
|
87
|
-
Piano::Base.play!
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "piano"
|
3
|
+
require "metafun/delegator"
|
4
|
+
|
5
|
+
unless ARGV.empty?
|
6
|
+
|
7
|
+
args = {}
|
8
|
+
|
9
|
+
ARGV.each do |arg|
|
10
|
+
if arg =~ /^\d+$/
|
11
|
+
args[:port] = arg
|
12
|
+
elsif arg =~ /^noetags$/
|
13
|
+
args[:etags] = :off
|
14
|
+
elsif arg == "-v"
|
15
|
+
puts Piano::VERSION
|
16
|
+
Process.exit!
|
17
|
+
elsif arg =~ /^views:/
|
18
|
+
matches = arg.match(/^views:(.+)$/)
|
19
|
+
args[:views] = matches[1]
|
20
|
+
elsif arg =~ /^public:/
|
21
|
+
matches = arg.match(/^public:(.+)$/)
|
22
|
+
args[:public] = matches[1]
|
23
|
+
elsif arg =~ /^[a-z]+$/
|
24
|
+
args[:environment] = arg.to_sym
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
if args
|
31
|
+
Piano::Base.port = args[:port] if args[:port]
|
32
|
+
Piano::Base.environment = args[:environment] if args[:environment]
|
33
|
+
Piano::Base.etags = args[:etags] if args[:etags]
|
34
|
+
Piano::Base.views = File.expand_path(Dir.pwd) + "/" +args[:views] if args[:views]
|
35
|
+
Piano::Base.public = File.expand_path(Dir.pwd) + "/" + args[:public] if args[:public]
|
36
|
+
end
|
37
|
+
|
38
|
+
self.extend Metafun::Delegator
|
39
|
+
self.delegate Piano::Base, :get, :patch, :put, :post, :delete,
|
40
|
+
:head, :options, :template, :layout,
|
41
|
+
:before, :after, :error, :not_found,
|
42
|
+
:configure, :set, :mime_type, :enable,
|
43
|
+
:disable, :use, :development?, :test?,
|
44
|
+
:production?, :helpers, :settings
|
45
|
+
|
46
|
+
self.helpers Sinatra::Piano
|
47
|
+
|
48
|
+
$LOAD_PATH << Dir.pwd
|
49
|
+
|
50
|
+
if File.exists?(File.expand_path(Dir.pwd) + "/Pianofile")
|
51
|
+
puts "Pianofile found, loading..."
|
52
|
+
load File.expand_path(Dir.pwd) + "/Pianofile"
|
53
|
+
end
|
54
|
+
|
55
|
+
if File.exist?("controllers") && File.directory?("controllers")
|
56
|
+
puts "'controllers' directory found, loading '.controller' files"
|
57
|
+
Piano::ControllerLoader.folder "controllers"
|
58
|
+
end
|
59
|
+
|
60
|
+
require "piano/routes"
|
61
|
+
|
62
|
+
Piano::Base.play!
|
data/bin/piano~
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "metafun/delegator"
|
3
|
+
|
4
|
+
unless ARGV.empty?
|
5
|
+
|
6
|
+
args = {}
|
7
|
+
|
8
|
+
ARGV.each do |arg|
|
9
|
+
if arg =~ /^\d+$/
|
10
|
+
args[:port] = arg
|
11
|
+
elsif arg =~ /^noetags$/
|
12
|
+
args[:etags] = :off
|
13
|
+
elsif arg =~ /^views:/
|
14
|
+
matches = arg.match(/^views:(.+)$/)
|
15
|
+
args[:views] = matches[1]
|
16
|
+
elsif arg =~ /^public:/
|
17
|
+
matches = arg.match(/^public:(.+)$/)
|
18
|
+
args[:public] = matches[1]
|
19
|
+
elsif arg =~ /^sample$/
|
20
|
+
puts "Warning: the sample site folder files will be created in the current directory."
|
21
|
+
puts "Any files with the same name will be overwritten."
|
22
|
+
print "Do you want to continue? (Yn): "
|
23
|
+
while answer = gets
|
24
|
+
puts answer
|
25
|
+
# if answer =~ /^Y/
|
26
|
+
# puts "Building sample..."
|
27
|
+
# make_sample
|
28
|
+
# break
|
29
|
+
# elsif answer =~ /^n/
|
30
|
+
# puts "Exiting now"
|
31
|
+
# Process.exit!
|
32
|
+
# else
|
33
|
+
# print "Couldn't understand the answer, please do it again (Yn): "
|
34
|
+
# end
|
35
|
+
end
|
36
|
+
elsif arg =~ /^[a-z]+$/
|
37
|
+
args[:environment] = arg.to_sym
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
require "piano"
|
44
|
+
|
45
|
+
if args
|
46
|
+
Piano::Base.port = args[:port] if args[:port]
|
47
|
+
Piano::Base.environment = args[:environment] if args[:environment]
|
48
|
+
Piano::Base.etags = args[:etags] if args[:etags]
|
49
|
+
Piano::Base.views = File.expand_path(Dir.pwd) + "/" +args[:views] if args[:views]
|
50
|
+
Piano::Base.public = File.expand_path(Dir.pwd) + "/" + args[:public] if args[:public]
|
51
|
+
end
|
52
|
+
|
53
|
+
def make_sample
|
54
|
+
require "fileutils"
|
55
|
+
|
56
|
+
source_dir = File.dirname(File.dirname(File.expand_path(__FILE__)))
|
57
|
+
|
58
|
+
this_dir = File.expand_path(Dir.pwd)
|
59
|
+
|
60
|
+
FileUtils.cp_r "#{source_dir}/sample", this_dir
|
61
|
+
end
|
62
|
+
|
63
|
+
self.extend Metafun::Delegator
|
64
|
+
self.delegate Piano::Base, :get, :patch, :put, :post, :delete,
|
65
|
+
:head, :options, :template, :layout,
|
66
|
+
:before, :after, :error, :not_found,
|
67
|
+
:configure, :set, :mime_type, :enable,
|
68
|
+
:disable, :use, :development?, :test?,
|
69
|
+
:production?, :helpers, :settings
|
70
|
+
|
71
|
+
self.helpers Sinatra::Piano
|
72
|
+
|
73
|
+
$LOAD_PATH << Dir.pwd
|
74
|
+
|
75
|
+
if File.exists?(File.expand_path(Dir.pwd) + "/Pianofile")
|
76
|
+
puts "Pianofile found, loading..."
|
77
|
+
load File.expand_path(Dir.pwd) + "/Pianofile"
|
78
|
+
end
|
79
|
+
|
80
|
+
if File.exist? "controllers" && File.directory? "controllers"
|
81
|
+
puts "'controllers' directory found, loading '.controller' files"
|
82
|
+
Piano::ControllerLoader.folder "controllers"
|
83
|
+
end
|
84
|
+
|
85
|
+
require "piano/routes"
|
86
|
+
|
87
|
+
Piano::Base.play!
|
data/lib/piano.rb
CHANGED
@@ -1,186 +1,46 @@
|
|
1
|
-
require "sinatra/base"
|
2
|
-
require "haml"
|
3
|
-
require "sass"
|
4
|
-
require "yaml"
|
5
|
-
require "i18n"
|
6
|
-
|
7
|
-
begin
|
8
|
-
require "coffee-script"
|
9
|
-
rescue Exception => error
|
10
|
-
puts "No JavaScript environment was found. Please install therubyracer gem"
|
11
|
-
puts " gem install therubyracer"
|
12
|
-
Process.exit!
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
# directory.
|
48
|
-
# Adds an etag if `etags?` is enabled and returns 404 and hints
|
49
|
-
# if it can't find the .coffee file.
|
50
|
-
def coffee(template)
|
51
|
-
file_name = "#{pwd}/#{template}.coffee"
|
52
|
-
bad_luck file_name unless File.exists? file_name
|
53
|
-
|
54
|
-
etag hash_for(template, :coffee) if etags?
|
55
|
-
CoffeeScript.compile(File.read(file_name))
|
56
|
-
end
|
57
|
-
|
58
|
-
# Loads and parses the YAML data from the data directory
|
59
|
-
def data_for(template)
|
60
|
-
file_name = "#{settings.data}/#{template}.yaml"
|
61
|
-
YAML.load_file(file_name) if File.exists?(file_name)
|
62
|
-
end
|
63
|
-
|
64
|
-
# Sugar: formats a css stylesheet <link /> tag with the input
|
65
|
-
def style(path)
|
66
|
-
"<link rel='stylesheet' type='text/css' href='#{path}' />"
|
67
|
-
end
|
68
|
-
|
69
|
-
# Sugar: formats a javascript <script> tag with the input
|
70
|
-
def script(path)
|
71
|
-
"<script type='text/javascript' src='#{path}'></script>"
|
72
|
-
end
|
73
|
-
|
74
|
-
# Returns the path to the :views directory
|
75
|
-
def pwd
|
76
|
-
settings.views
|
77
|
-
end
|
78
|
-
|
79
|
-
# Fails. Shouts a 404 response and prints hints
|
80
|
-
#
|
81
|
-
# If Piano is running in production mode, prints a plain 404 html
|
82
|
-
# or, if a 404.haml exists in the :views directory, returns it
|
83
|
-
def bad_luck(path)
|
84
|
-
content_type :html
|
85
|
-
if settings.environment == :production
|
86
|
-
if File.exists? "#{pwd}/404.haml"
|
87
|
-
@data = data_for "404"
|
88
|
-
halt 404, haml(:"404")
|
89
|
-
else
|
90
|
-
halt 404, "<h1>404 - Not Found</h1><p>Piano has found nothing in this address</p>"
|
91
|
-
end
|
92
|
-
else
|
93
|
-
halt 404, "<h1>You have still to put something here.</h1><p>This is <em>#{path}</em></p><blockquote>Good luck!</blockquote>"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# Builds a hash for a file within the :views directory
|
98
|
-
# Note: I feel like this functionality should be private
|
99
|
-
def hash_for(name, type)
|
100
|
-
"#{name}.#{type} - " + File.mtime("#{pwd}/#{name}.#{type}").to_s
|
101
|
-
end
|
102
|
-
|
103
|
-
# Makes an extract out of the given text with the default length
|
104
|
-
# of 80 words
|
105
|
-
#
|
106
|
-
# If an integer is passed as the second argument, the length
|
107
|
-
# of the result is adjusted properly:
|
108
|
-
#
|
109
|
-
# extract "Hello World! Too much text is inconvenient", 2
|
110
|
-
#
|
111
|
-
# returns
|
112
|
-
#
|
113
|
-
# => "Hello World!..."
|
114
|
-
#
|
115
|
-
def extract(text, length = 80)
|
116
|
-
words = text.gsub(/<.+?>/, "").split
|
117
|
-
return text if words.length <= length
|
118
|
-
words[0..(length-1)].join(" ") + "..."
|
119
|
-
end
|
120
|
-
|
121
|
-
# Returns a url-friendly version of the given link, with a
|
122
|
-
# default maximum of 5 words.
|
123
|
-
# `link` strips any non-letter or special character, downcases the
|
124
|
-
# string and replaces whitespace with "-"
|
125
|
-
# For example:
|
126
|
-
#
|
127
|
-
# link "This is a special text! This won't be shown"
|
128
|
-
#
|
129
|
-
# returns
|
130
|
-
#
|
131
|
-
# => "this-is-a-special-text"
|
132
|
-
#
|
133
|
-
# You can specify a word length in the second argument.
|
134
|
-
def link(text, length = 5)
|
135
|
-
words = text.gsub(/<.+?>/, "").gsub(" ", "-").downcase.gsub(/[^a-z0-9\-]/, "").split("-")
|
136
|
-
words[0..(length-1)].join("-")
|
137
|
-
end
|
138
|
-
|
139
|
-
# Shorthand to settings.etags == :on
|
140
|
-
def etags?
|
141
|
-
if settings.respond_to? :etags
|
142
|
-
settings.etags == :on
|
143
|
-
else
|
144
|
-
true
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
# Non implemented yet
|
149
|
-
def t(key)
|
150
|
-
I18n.translate key
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
register Piano
|
155
|
-
end
|
156
|
-
|
157
|
-
|
158
|
-
module Piano
|
159
|
-
class Base < Sinatra::Base
|
160
|
-
register Sinatra::Piano
|
161
|
-
|
162
|
-
set :root, File.expand_path(Dir.pwd)
|
163
|
-
set :views, File.expand_path(Dir.pwd)
|
164
|
-
set :data, File.expand_path(Dir.pwd + "/data")
|
165
|
-
set :etags, :on
|
166
|
-
set :i18n_path, File.expand_path(Dir.pwd) + "/config/locale"
|
167
|
-
|
168
|
-
def self.i18n!
|
169
|
-
return unless Dir.exists? self.i18n_path
|
170
|
-
dir = Dir.new self.i18n_path
|
171
|
-
i18n_files = []
|
172
|
-
dir.each do |file|
|
173
|
-
if file.end_with?(".yml") or file.end_with?(".yaml")
|
174
|
-
i18n_files << "#{dir.path}/#{file}"
|
175
|
-
end
|
176
|
-
end
|
177
|
-
I18n.load_path = i18n_files
|
178
|
-
end
|
179
|
-
|
180
|
-
def self.play!
|
181
|
-
self.run!
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
require "piano/controllerloader"
|
1
|
+
require "sinatra/base"
|
2
|
+
require "haml"
|
3
|
+
require "sass"
|
4
|
+
require "yaml"
|
5
|
+
require "i18n"
|
6
|
+
|
7
|
+
begin
|
8
|
+
require "coffee-script"
|
9
|
+
rescue Exception => error
|
10
|
+
puts "No JavaScript environment was found. Please install therubyracer gem"
|
11
|
+
puts " gem install therubyracer"
|
12
|
+
Process.exit!
|
13
|
+
end
|
14
|
+
|
15
|
+
require "sinatra/piano"
|
16
|
+
|
17
|
+
module Piano
|
18
|
+
class Base < Sinatra::Base
|
19
|
+
register Sinatra::Piano
|
20
|
+
|
21
|
+
set :root, File.expand_path(Dir.pwd)
|
22
|
+
set :views, File.expand_path(Dir.pwd)
|
23
|
+
set :data, File.expand_path(Dir.pwd + "/data")
|
24
|
+
set :etags, :on
|
25
|
+
set :i18n_path, File.expand_path(Dir.pwd) + "/config/locale"
|
26
|
+
|
27
|
+
def self.i18n!
|
28
|
+
return unless Dir.exists? self.i18n_path
|
29
|
+
dir = Dir.new self.i18n_path
|
30
|
+
i18n_files = []
|
31
|
+
dir.each do |file|
|
32
|
+
if file.end_with?(".yml") or file.end_with?(".yaml")
|
33
|
+
i18n_files << "#{dir.path}/#{file}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
I18n.load_path = i18n_files
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.play!
|
40
|
+
self.run!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require "piano/controllerloader"
|
46
|
+
require "piano/version"
|