beds 0.0.2 → 0.1.2

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/beds CHANGED
@@ -1,70 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
- require 'beds'
3
- @options = {
4
- :viewdir => "./views",
5
- :routefile => "./scaffold.rb",
6
- :list => true,
7
- :save => true,
8
- :template => true,
9
- :new => true,
10
- :index => true,
11
- :exclude => []
12
- }
13
- optparser = OptionParser.new do |opts|
14
- opts.banner = " Usage: #{File.basename($0)} -m <models.rb> [OPTIONS]"
15
- opts.on("-m","--models FILE", "Specify file with DataMapper models defined.") do |app|
16
- @options[:app] = app
17
- end
18
- opts.on("-v","--viewdir","Specify which directory to place the views in. Default: ./views/") do |viewdir|
19
- @options[:viewdir] = viewdir
20
- end
21
- opts.on("-r","--routefile", "Sepcify the file to generate the routes in. Default: scaffold.rb") do |routefile|
22
- @options[:routefile] = routefile
23
- end
24
- opts.on("--exclude x,y,z", Array, "Do not generate anything for specified models, or before, index, and/or layout") do |models|
25
- @options[:exclude] = models
26
- end
27
- opts.on("--only x,y,z", Array, "Only process the specified models.") do |models|
28
- @options[:only] = models
29
- end
30
- opts.on("-f","--[no-]force", "Overwtie files") do |force|
31
- @options[:force] = force
32
- end
33
- end
34
-
35
- begin
36
- optparser.parse! ARGV
37
- raise OptionParser::InvalidOption, "[NONE]" if @options[:app].nil?
38
- rescue OptionParser::InvalidOption => e
39
- puts e
40
- puts optparser
41
- exit 1
42
- end
43
-
44
-
45
-
46
- load "#{@options[:app]}"
47
- scaffold = SinScaffold.new(@options)
48
- scaffold.generate
49
-
50
- ### Write Files
51
-
52
- if File.exist?(@options[:routefile]) and ! @options[:force] then
53
- puts "Error: Route file #{@options[:routefile]} already exists. Not writing"
2
+ require "#{File.dirname(__FILE__)}/../lib/beds.rb"
3
+ require "#{File.dirname(__FILE__)}/../lib/cli.rb"
4
+
5
+ ## A bit of magic to call Beds::CLI::<CLI-Command>
6
+ cmd = ARGV[0].nil? ? "" : ARGV[0]
7
+ if ! cmd == "" and Beds::CLI.const_defined?(cmd.capitalize.to_sym) then
8
+ Beds::CLI.const_get(cmd.capitalize.to_sym).send(:new,ARGV[1..-1])
9
+ exit 0
54
10
  else
55
- File.open(@options[:routefile],"w") {|file| file.write(scaffold.routes.join("\n"))}
11
+ puts " Usage: #{File.basename($0)} [scaffold|new] [OPTIONS]"
12
+ puts " See #{File.basename($0)} scaffold --help or #{File.basename($0)} new --help foor more information"
13
+ exit 1
56
14
  end
57
15
 
58
- Dir.mkdir(@options[:viewdir]) unless Dir.exist?(@options[:viewdir])
59
-
60
- @gen_files = []
61
- scaffold.views.each {|file,content|
62
- if File.exist?(File.join(@options[:viewdir],file)) and ! @options[:force] then
63
- puts "Warning: file #{File.join(@options[:viewdir],file)} exists. Not overwriting"
64
- else
65
- @gen_files << File.join(@options[:viewdir],file)
66
- File.open(File.join(@options[:viewdir],file),"w") {|file| file.write(content) }
67
- end
68
- }
69
16
 
70
- puts "Generated files: #{@gen_files.join(", ")}"
data/lib/beds.rb CHANGED
@@ -1,298 +1,98 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'erb'
3
3
  require 'optparse'
4
+ ## == Beds - BootStrap Erb DataMapper Sinatra [Scaffolder]
5
+ ##
6
+ ## * For general information on using Beds to scaffold your Sinatra projects please see README.rdoc
7
+ ## * Or see Beds:Scaffold
4
8
 
5
- class SinScaffold
6
- STATIC_ROUTE_TEMPLATES = {
7
- :before => %q^
8
- before do
9
- @active_page = request.path_info.split(/\//)[1]
10
- @active_page = "index" if @active_page.nil?
9
+ module Beds
10
+ ## Generates Scaffolds based off of DataMappr models.
11
+ class Scaffold
12
+ # Returns an array of generated routes
13
+ attr_reader :routes
14
+ # Returns an array of views and file names.
15
+ attr_reader :views
16
+ # Returns a hash containing file_name => file_contents key pairs.
17
+ attr_reader :templates
18
+ ## * opts should be a hash
19
+ ## * Defautly loads data for all models.
20
+ ##
21
+ ## Valid Options:
22
+ ## :only - An array that only generates views for the specified models.
23
+ ## :exclude - An array containing models that should not be generatd.
24
+ def initialize(opts = {:exclude => [], :only => nil})
25
+ @routes = {}
26
+ @views = {}
27
+ @models = []
28
+ @opts = opts
29
+ DataMapper::Model.descendants.entries.each {|entry|
30
+ @models << entry
31
+ }
32
+ @models.delete_if { |model| @opts[:exclude].include? model.name or @opts[:exclude].include? model.name.downcase }
33
+ @models.select! { |model| @opts[:only].include? model.name or @opts[:only].include? model.name.downcase } unless @opts[:only].nil?
34
+ load_templates
35
+ end
36
+ ## Generate views and routes for models. Will genrate the *view* and *routes* attributes.
37
+ def generate
38
+ result = Hash.new
39
+ routes = Hash.new
40
+ @templates[:static_routes].each { |key,value| next if @opts[:exclude].include? key.to_s; puts "Processing Route: #{key}"; @routes['default'] ||= String.new ; @routes['default'] << ERB.new(value,nil,"<>").result(binding) } if @opts[:only].nil?
41
+ @templates[:static_erb].each { |key,value| next if @opts[:exclude].include? key.to_s; puts "Processing Template: #{key}";@views["#{key.to_s}.erb"]=ERB.new(value,nil,"<>").result(binding) } if @opts[:only].nil?
42
+ @models.each { |entry|
43
+ @model_name = entry.inspect
44
+ @properties = entry.properties
45
+ puts "Processing Model: #{@model_name}"
46
+ @templates[:routes].each {|key,value|
47
+ @routes[entry.to_s.downcase] ||= String.new
48
+ @routes[entry.to_s.downcase] << ERB.new(value,nil,"<>").result(binding)
49
+ }
50
+ @templates[:erb].each { |key,value|
51
+ @views["#{key.to_s}_#{@model_name.downcase}.erb"] = ERB.new(value,nil,"<>").result(binding)
52
+ }
53
+ }
54
+ return true
55
+ end
56
+ private
57
+ ## Called by .new, Locates and loads templaes into memory.
58
+ def load_templates
59
+ home_dir = "~/.beds"
60
+ template_dir = "#{File.dirname(__FILE__)}/../templates"
61
+ @templates=Hash.new
62
+ @templates[:static_routes] = { }
63
+ @templates[:static_erb] = { }
64
+ @templates[:routes] = { }
65
+ @templates[:erb] = { }
66
+ @templates[:hooks] = { }
67
+ @templates.each do |key,val|
68
+ template_files = Dir.exist?("#{home_dir}/#{key.to_s}") ? Dir.glob("/#{home_dir}/#{key.to_s}/*") : Dir.glob("/#{template_dir}/#{key.to_s}/*")
69
+ template_files.each { |file| @templates[key][File.basename(file).sub(/\.erb$/,"")] = File.open(file).read }
11
70
  end
12
- ^,
13
- :index => %Q^
14
- get '/' do
15
- erb :index
16
71
  end
17
- ^ }
18
- STATIC_ERB_TEMPLATES = {
19
- :layout => %Q^
20
- <!DOCTYPE html>
21
- <html lang="en">
22
- <head>
23
- <meta charset="utf-8">
24
- <title>Application</title>
25
- <meta name="GeneratedBy" content="sdbscaffold"
26
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
27
- <meta name="description" content="">
28
- <meta name="author" content="">
29
- <!-- Le styles -->
72
+
73
+ ## Determines the type of form to generate for DataMapper objects.
74
+ def form_type(object,properties)
75
+ append = String.new
76
+ properties.each {|key,value|
77
+ append << " #{key}='#{value}'"
78
+ }
30
79
 
31
- <link href="/assets/css/bootstrap.css" rel="stylesheet">
32
- <link href="/style.css" rel="stylesheet">
33
- <style>
34
- body {
35
- padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
36
- }
37
- </style>
38
-
39
- <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
40
- <!--[if lt IE 9]>
41
- <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
42
- <![endif]-->
43
- <script src="/assets/js/jquery.js" type="text/javascript"></script>
44
- <script>
45
- $(document).ready(function() {
46
- $("#<%%=@active_page%>").addClass("active");
47
- });
48
- </script>
49
- <!-- Le fav and touch icons -->
50
- <link rel="shortcut icon" href="/assets/ico/favicon.ico">
51
- <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/assets/ico/apple-touch-icon-144-precomposed.png">
52
- <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/assets/ico/apple-touch-icon-114-precomposed.png">
53
- <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/assets/ico/apple-touch-icon-72-precomposed.png">
54
- <link rel="apple-touch-icon-precomposed" href="/assets/ico/apple-touch-icon-57-precomposed.png">
55
- </head>
56
-
57
- <body>
58
-
59
- <div class="navbar navbar-fixed-top">
60
- <div class="navbar-inner">
61
- <div class="container">
62
- <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
63
- <span class="icon-bar"></span>
64
- <span class="icon-bar"></span>
65
- <span class="icon-bar"></span>
66
- </a>
67
- <a class="brand" href="#">YourApp</a>
68
- <div class="nav-collapse">
69
- <ul class="nav">
70
- <li class="divider-vertical"></li>
71
- <li id="index" ><a href="/">Home</a></li>
72
- <% @models.each do |model| %>
73
- <li id="<%=model.name.downcase%>" ><a href="/<%=model.name.downcase%>/"><%= model.name %></a></li>
74
- <% end %>
75
- </ul>
76
- <ul class="nav pull-right">
77
- <li class="divider-vertical"></li>
78
- <li><a href="/login">Log<%%= session[:valid] ? "out" : "in"%></a></li>
79
- </ul>
80
- </div><!--/.nav-collapse -->
81
- </div>
82
- </div>
83
- </div>
84
-
85
- <div class="container">
86
- <%% if ! @flash.nil? then %>
87
- <span class="span9 offset1">
88
- <%% @flash.each do |alert| %>
89
- <div class="alert alert-<%%=alert[:level].downcase%>" style="margin:0px; margin-bottom:8px;">
90
- <button class="close" data-dismiss="alert">x</button>
91
- <strong><%%=alert[:level].capitalize%>!</strong> <%%=alert[:message]%>
92
- </div>
93
- <%% end %>
94
- </span>
95
- <%%end %>
96
- <%%= yield %>
97
- </div> <!-- /container -->
98
-
99
- <!-- Le javascript
100
- ================================================== -->
101
- <!-- Placed at the end of the document so the pages load faster -->
102
- <script src="/assets/js/bootstrap.min.js"></script>
103
- </body>
104
- </html>
105
- ^,
106
- :index => %Q^
107
- <div class="well">
108
- <div class="hero-unit">
109
- <h1>Models</h1>
110
- <p class="btn-group">
111
- <% @models.each do |model| %>
112
- <a class="btn btn-large btn-info" href="/<%=model.name.downcase%>/"><%= model.name %></a>
113
- <% end %>
114
- </p>
115
- </div>
116
- </div>
117
- ^
118
- }
119
- ROUTE_TEMPLATES = {
120
- :list => %Q^
121
- get '/<%=@model_name.downcase%>/?' do
122
- @offset = params["page"] if params["page"] =~ /[0-9]+/
123
- @offset ||= 0
124
- @db_objects = <%=@model_name%>.all(:limit => 20,:offset => @offset * 20)
125
- erb :list_<%=@model_name.downcase%>
126
- end
127
- ^,
128
- :new => %q^
129
- get '/<%=@model_name.downcase%>/new/?' do
130
- erb :new_<%=@model_name.downcase%>
131
- end
132
- ^,
133
- :save => %q^
134
- post '/<%=@model_name.downcase%>/save/?' do
135
- db_object = <%=@model_name%>.new
136
- params.each do |key,value|
137
- db_object.send("#{key}=",value) if <%=@model_name%>.properties.collect{|x| x.name}.include? key.to_sym
138
- end
139
- if db_object.save then
140
- redirect "/<%=@model_name.downcase%>/#{db_object.id}"
141
- else
142
- result = []
143
- db_object.errors.each do |e|
144
- result << "<li>#{e}</li>"
145
- end
146
- return "<UL>#{result.join("")}</UL>"
147
- end
148
- end
149
- ^,
150
- :edit => %q^
151
- get '/<%=@model_name.downcase%>/:id/?' do |id|
152
- pass if "#{id.to_i}" != "#{id}"
153
- @db_object = <%=@model_name%>.first(:id => id)
154
- return 404 if @db_object.nil?
155
- erb :edit_<%=@model_name.downcase%>
156
- end
157
-
158
- post '/<%=@model_name.downcase%>/:id/?' do |id|
159
- db_object = <%=@model_name%>.first(:id => id)
160
- redirect 404 if ! db_object
161
- params.each do |key,value|
162
- db_object.send("#{key}=",value) if <%=@model_name%>.properties.collect{|x| x.name}.include? key.to_sym
163
- end
164
- if db_object.save then
165
- redirect "/<%=@model_name.downcase%>/#{db_object.id}"
166
- else
167
- result = []
168
- db_object.errors.each do |e|
169
- STDERR.puts e
170
- result << "<li>#{e}</li>"
171
- end
172
- return "<UL>#{result.join("")}</UL>"
173
- end
174
- end
175
- ^,
176
- :delete => %q^
177
- get '/<%=@model_name.downcase%>/delete/:id/?' do |id|
178
- db_object = <%=@model_name%>.first(:id => id)
179
- if db_object then
180
- db_object.destroy
181
- redirect '/<%=@model_name.downcase%>/'
182
- else
183
- redirect 404
184
- end
185
- end
186
- ^
187
- }
188
- ERB_TEMPLATES = {
189
- :list => %Q^
190
- <a href="/<%=@model_name.downcase%>/new" class="btn btn-info">New</a>
191
- <table class="table table-bordered">
192
- <thead>
193
- <% @properties.each do |header| %>
194
- <th><%=header.name%></th>
195
- <% end %>
196
- <th>Actions</th>
197
- </thead>
198
- <tbody>
199
- <%% @db_objects.each do |object| %>
200
- <tr>
201
- <% @properties.each do |prop| %>
202
- <td><%%=object.<%=prop.name%>%></td>
203
- <%end%>
204
- <td><a href="/<%=@model_name.downcase%>/<%%=object.id%>" class="btn btn-mini">Edit</a>
205
- <a href="/<%=@model_name.downcase%>/delete/<%%=object.id%>" class="btn btn-mini">Delete</a></td>
206
- </tr>
207
- <%%end%>
208
- </tbody>
209
- </table>
210
- ^,
211
- :new => %q^
212
- <form class="well row" method="post" action="/<%=@model_name.downcase%>/save">
213
- <% @properties.each do |prop| %>
214
- <% next if prop.name == :id %>
215
- <label><%=prop.name.to_s%></label>
216
- <%=form_type(prop,:name => prop.name)%>
217
-
218
- <% end %>
219
- <button type="submit" class="btn">Submit</button>
220
- </form>
221
- ^,
222
- :edit => %q^
223
- <form class="well" method="post" action="/<%=@model_name.downcase%>/<%%= @db_object.id%>">
224
- <% @properties.each do |prop| %>
225
- <% next if prop.name == :id %>
226
- <label><%=prop.name.to_s%></label>
227
- <%=form_type(prop,:name => prop.name,:value => "<%= @db_object.#{prop.name} %%>")%>
228
-
229
- <% end %>
230
- <button type="submit" class="btn">Submit</button>
231
- </form>
232
- ^
233
- }
234
-
235
- def initialize(opts)
236
- @routes = []
237
- @views = {}
238
- @models = []
239
- @opts = opts
240
- DataMapper::Model.descendants.entries.each {|entry|
241
- @models << entry
242
- #@model_name=entry.inspect
243
- #@properties=entry.properties
244
-
245
- #puts ERB.new(ERB_TEMPLATES[:new]).result(binding)
246
- }
247
- @models.delete_if { |model| @opts[:exclude].include? model.name or @opts[:exclude].include? model.name.downcase }
248
- @models.select! { |model| @opts[:only].include? model.name or @opts[:only].include? model.name.downcase } unless @opts[:only].nil?
249
- end
250
- def generate
251
- result = Hash.new
252
- routes = Hash.new
253
- STATIC_ROUTE_TEMPLATES.each { |key,value| next if @opts[:exclude].include? key.to_s; puts "Processing Route: #{key}"; @routes << ERB.new(value,nil,"<>").result(binding) } if @opts[:only].nil?
254
- STATIC_ERB_TEMPLATES.each { |key,value| next if @opts[:exclude].include? key.to_s; puts "Processing Template: #{key}";@views["#{key.to_s}.erb"]=ERB.new(value,nil,"<>").result(binding) } if @opts[:only].nil?
255
- @models.each { |entry|
256
- @model_name = entry.inspect
257
- @properties = entry.properties
258
- puts "Processing Model: #{@model_name}"
259
- ROUTE_TEMPLATES.each {|key,value|
260
- @routes << ERB.new(value,nil,"<>").result(binding)
261
- }
262
- ERB_TEMPLATES.each { |key,value|
263
- @views["#{key.to_s}_#{@model_name.downcase}.erb"] = ERB.new(value,nil,"<>").result(binding)
264
- }
265
- }
266
- return true
267
- end
268
- def routes
269
- @routes
270
- end
271
- def views
272
- @views
273
- end
274
- private
275
- def form_type(object,properties)
276
- append = String.new
277
- properties.each {|key,value|
278
- append << " #{key}='#{value}'"
279
- }
280
-
281
- case object
282
- when DataMapper::Property::Serial
283
- ""
284
- when DataMapper::Property::String
285
- "<input type='text' class='span2' #{append} />"
286
- when DataMapper::Property::Boolean
287
- "<input type='checkbox' #{append}/>"
288
- when DataMapper::Property::Text
289
- "<textbox class='span3' #{append - append[:value]}>#{append[:value] unless append[:value].nil?}</textbox>"
290
- when DataMapper::Property::Float, DataMapper::Property::Integer, DataMapper::Property::Decimal
291
- "<input type='text' class='span1' #{append} />"
292
- when DateTime, Date, Time
293
- "<input type='text' class='span2' #{append} />"
294
- else
295
- "<input type='text' class='span1' #{append} />"
296
- end
297
- end
80
+ case object
81
+ when DataMapper::Property::Serial # Serial #'s should be generated. Do not create a form for entry for it.
82
+ ""
83
+ when DataMapper::Property::String
84
+ "<input type='text' class='span2' #{append} />"
85
+ when DataMapper::Property::Boolean
86
+ "<input type='checkbox' #{append}/>"
87
+ when DataMapper::Property::Text
88
+ "<textbox class='span3' #{append - append[:value]}>#{append[:value] unless append[:value].nil?}</textbox>"
89
+ when DataMapper::Property::Float, DataMapper::Property::Integer, DataMapper::Property::Decimal
90
+ "<input type='text' class='span1' #{append} />"
91
+ when DateTime, Date, Time
92
+ "<input type='text' class='span2' #{append} />"
93
+ else
94
+ "<input type='text' class='span1' #{append} />"
95
+ end
96
+ end
97
+ end
298
98
  end
data/lib/cli.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "#{File.dirname(__FILE__)}/scaffold"
2
+ require "#{File.dirname(__FILE__)}/new"
3
+
data/lib/new.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Beds
2
+ module CLI
3
+ class New
4
+ end
5
+ end
6
+ end
data/lib/scaffold.rb ADDED
@@ -0,0 +1,102 @@
1
+ module Beds
2
+ module CLI
3
+ class Scaffold
4
+ def initialize(options)
5
+ @options = {
6
+ :viewdir => "./views",
7
+ :public => "./public",
8
+ :controllers => "./controllers",
9
+ :routefile => "./scaffold.rb",
10
+ :list => true,
11
+ :save => true,
12
+ :template => true,
13
+ :new => true,
14
+ :index => true,
15
+ :run_hooks => true,
16
+ :exclude => []
17
+ }; @options[:assets] = "#{@options[:public]}/assets"
18
+ get_options(options)
19
+ load_models
20
+ make_files
21
+ run_hooks if @options[:run_hooks]
22
+ end
23
+ private
24
+ # Run post-scaffold hooks
25
+ def run_hooks
26
+ #begin
27
+ @scaffold.templates[:hooks].each {|key,hook| puts "Running hook: #{key}"; instance_eval(hook) }
28
+ #rescue Exception => e
29
+ # puts "Error running hook #{e.message}"
30
+ #end
31
+ end
32
+ ## Load model data from data mapper
33
+ def load_models
34
+ begin
35
+ load "#{@options[:app]}"
36
+ rescue Exception => e
37
+ puts "Unable to load models. #{e.message}"
38
+ exit 1
39
+ end
40
+ @scaffold = Beds::Scaffold.new(@options)
41
+ @scaffold.generate
42
+ end
43
+
44
+ ## Write the generated files to disk.
45
+ def make_files
46
+ @gen_files = []
47
+ [@options[:viewdir],@options[:public],@options[:assets],@options[:controllers]].each {|directory| Dir.mkdir(directory) unless Dir.exist?(directory) }
48
+ @scaffold.routes.each do |controller,contents|
49
+ if File.exist?(File.join(@options[:controllers],"#{controller}.rb")) and @options[:force] != true then
50
+ puts "Error: Controller #{File.join(@options[:controllers],"#{controller}.rb")} already exists. Not writing"
51
+ else
52
+ File.open(File.join(@options[:controllers],"#{controller}.rb"),"w") {|file| file.write(contents) }
53
+ @gen_files << File.join(@options[:controllers],"#{controller}.rb")
54
+ end
55
+ end
56
+
57
+ @scaffold.views.each {|file,content|
58
+ if File.exist?(File.join(@options[:viewdir],file)) and ! @options[:force] then
59
+ puts "Warning: file #{File.join(@options[:viewdir],file)} exists. Not overwriting"
60
+ else
61
+ @gen_files << File.join(@options[:viewdir],file)
62
+ File.open(File.join(@options[:viewdir],file),"w") {|file| file.write(content) }
63
+ end
64
+ }
65
+
66
+ puts "Generated files: #{@gen_files.join(", ")}"
67
+ end
68
+ ## Get optoins from CLI input
69
+ def get_options(options)
70
+ optparser = OptionParser.new do |opts|
71
+ opts.banner = " Usage: #{File.basename($0)} scaffold -m <models.rb> [OPTIONS]"
72
+ opts.on("-m","--models FILE", "Specify file with DataMapper models defined.") do |app|
73
+ @options[:app] = app
74
+ end
75
+ opts.on("-v","--viewdir","Specify which directory to place the views in. Default: ./views/") do |viewdir|
76
+ @options[:viewdir] = viewdir
77
+ end
78
+ opts.on("-r","--routefile", "Sepcify the file to generate the routes in. Default: scaffold.rb") do |routefile|
79
+ @options[:routefile] = routefile
80
+ end
81
+ opts.on("--exclude x,y,z", Array, "Do not generate anything for specified models, or before, index, and/or layout") do |models|
82
+ @options[:exclude] = models
83
+ end
84
+ opts.on("--only x,y,z", Array, "Only process the specified models.") do |models|
85
+ @options[:only] = models
86
+ end
87
+ opts.on("-f","--[no-]force", "Overwtie files") do |force|
88
+ @options[:force] = force
89
+ end
90
+ end
91
+ begin
92
+ optparser.parse! options
93
+ raise OptionParser::InvalidOption, "[NONE]" if @options[:app].nil?
94
+ rescue OptionParser::InvalidOption => e
95
+ puts e
96
+ puts optparser
97
+ exit 1
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,8 @@
1
+ <form class="well" method="post" action="/<%=@model_name.downcase%>/<%%= @db_object.id%>">
2
+ <% @properties.each do |prop| %>
3
+ <% next if prop.name == :id %>
4
+ <label><%=prop.name.to_s%></label>
5
+ <%=form_type(prop,:name => prop.name,:value => "<%= @db_object.#{prop.name} %%>")%>
6
+ <% end %>
7
+ <button type="submit" class="btn">Submit</button>
8
+ </form>
@@ -0,0 +1,21 @@
1
+ <a href="/<%=@model_name.downcase%>/new" class="btn btn-info">New</a>
2
+ <table class="table table-bordered">
3
+ <thead>
4
+ <% @properties.each do |header| %>
5
+ <th><%=header.name%></th>
6
+ <% end %>
7
+ <th>Actions</th>
8
+ </thead>
9
+ <tbody>
10
+ <%% @db_objects.each do |object| %>
11
+ <tr>
12
+ <% @properties.each do |prop| %>
13
+ <td><%%=object.<%=prop.name%>%></td>
14
+ <%end%>
15
+ <td><a href="/<%=@model_name.downcase%>/<%%=object.id%>" class="btn btn-mini">Edit</a>
16
+ <a href="/<%=@model_name.downcase%>/delete/<%%=object.id%>" class="btn btn-mini">Delete</a></td>
17
+ </tr>
18
+ <%%end%>
19
+ </tbody>
20
+ </table>
21
+
@@ -0,0 +1,9 @@
1
+ <form class="well row" method="post" action="/<%=@model_name.downcase%>/save">
2
+ <% @properties.each do |prop| %>
3
+ <% next if prop.name == :id %>
4
+ <label><%=prop.name.to_s%></label>
5
+ <%=form_type(prop,:name => prop.name)%>
6
+ <% end %>
7
+ <button type="submit" class="btn">Submit</button>
8
+ </form>
9
+
@@ -0,0 +1,14 @@
1
+ require 'open-uri'
2
+ require 'zip/zip'
3
+ require 'fileutils'
4
+ BOOTSTRAP_ZIP_URL="http://twitter.github.com/bootstrap/assets/bootstrap.zip"
5
+
6
+ File.open("bootstrap.zip","w") {|file| file.write(open(BOOTSTRAP_ZIP_URL).read) }
7
+ Zip::ZipFile.open('bootstrap.zip') { |zip_file|
8
+ zip_file.each { |f|
9
+ f_path=File.join("#{@options[:public]}/assets", f.name)
10
+ FileUtils.mkdir_p(File.dirname(f_path))
11
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
12
+ }
13
+ }
14
+ File.delete("bootstrap.zip")
@@ -0,0 +1,7 @@
1
+ require 'open-uri'
2
+ require 'fileutils'
3
+ JQUERY_URL="http://code.jquery.com/jquery-1.8.1.min.js"
4
+ f_path=File.join("#{@options[:public]}/assets/js")
5
+ FileUtils.mkdir_p(File.dirname(f_path))
6
+ File.open("#{f_path}/jquery.min.js") { |file| file.write(open(JQUERY_URL).read) }
7
+
@@ -0,0 +1,10 @@
1
+ get '/<%=@model_name.downcase%>/delete/:id/?' do |id|
2
+ db_object = <%=@model_name%>.first(:id => id)
3
+ if db_object then
4
+ db_object.destroy
5
+ redirect '/<%=@model_name.downcase%>/'
6
+ else
7
+ redirect 404
8
+ end
9
+ end
10
+
@@ -0,0 +1,25 @@
1
+ get '/<%=@model_name.downcase%>/:id/?' do |id|
2
+ pass if "#{id.to_i}" != "#{id}"
3
+ @db_object = <%=@model_name%>.first(:id => id)
4
+ return 404 if @db_object.nil?
5
+ erb :edit_<%=@model_name.downcase%>
6
+ end
7
+
8
+ post '/<%=@model_name.downcase%>/:id/?' do |id|
9
+ db_object = <%=@model_name%>.first(:id => id)
10
+ pass if ! db_object
11
+ params.each do |key,value|
12
+ db_object.send("#{key}=",value) if <%=@model_name%>.properties.collect{|x| x.name}.include? key.to_sym
13
+ end
14
+ if db_object.save then
15
+ redirect "/<%=@model_name.downcase%>/#{db_object.id}"
16
+ else
17
+ result = []
18
+ db_object.errors.each do |e|
19
+ STDERR.puts e
20
+ result << "<li>#{e}</li>"
21
+ end
22
+ return "<UL>#{result.join("")}</UL>"
23
+ end
24
+ end
25
+
@@ -0,0 +1,7 @@
1
+ get '/<%=@model_name.downcase%>/?' do
2
+ @offset = params["page"] if params["page"] =~ /[0-9]+/
3
+ @offset ||= 0
4
+ @db_objects = <%=@model_name%>.all(:limit => 20,:offset => @offset * 20)
5
+ erb :list_<%=@model_name.downcase%>
6
+ end
7
+
@@ -0,0 +1,4 @@
1
+ get '/<%=@model_name.downcase%>/new/?' do
2
+ erb :new_<%=@model_name.downcase%>
3
+ end
4
+
@@ -0,0 +1,17 @@
1
+ post '/<%=@model_name.downcase%>/save' do
2
+ db_object = <%=@model_name%>.new
3
+ params.each do |key,value|
4
+ db_object.send("#{key}=",value) if <%=@model_name%>.properties.collect{|x| x.name}.include? key.to_sym
5
+ end
6
+ if db_object.save! then
7
+ redirect "/<%=@model_name.downcase%>/#{db_object.id}"
8
+ else
9
+ result = []
10
+ db_object.errors.each do |e|
11
+ result << "Error:<li>#{e}</li>"
12
+ end
13
+ return "<UL>#{result.join("")}</UL>"
14
+ end
15
+ return "YAY"
16
+ end
17
+
@@ -0,0 +1,10 @@
1
+ <div class="well">
2
+ <div class="hero-unit">
3
+ <h1>Models</h1>
4
+ <p class="btn-group">
5
+ <% @models.each do |model| %>
6
+ <a class="btn btn-large btn-info" href="/<%=model.name.downcase%>/"><%= model.name %></a>
7
+ <% end %>
8
+ </p>
9
+ </div>
10
+ </div>
@@ -0,0 +1,86 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Application</title>
6
+ <meta name="GeneratedBy" content="sdbscaffold"
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <meta name="description" content="">
9
+ <meta name="author" content="">
10
+ <!-- Le styles -->
11
+
12
+ <link href="/assets/bootstrap/css/bootstrap.css" rel="stylesheet">
13
+ <link href="/style.css" rel="stylesheet">
14
+ <style>
15
+ body {
16
+ padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
17
+ }
18
+ </style>
19
+
20
+ <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
21
+ <!--[if lt IE 9]>
22
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
23
+ <![endif]-->
24
+ <script src="/assets/bootstrap/js/jquery.js" type="text/javascript"></script>
25
+ <script>
26
+ $(document).ready(function() {
27
+ $("#<%%=@active_page%>").addClass("active");
28
+ });
29
+ </script>
30
+ <!-- Le fav and touch icons -->
31
+ <link rel="shortcut icon" href="/assets/ico/favicon.ico">
32
+ <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/assets/ico/apple-touch-icon-144-precomposed.png">
33
+ <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/assets/ico/apple-touch-icon-114-precomposed.png">
34
+ <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/assets/ico/apple-touch-icon-72-precomposed.png">
35
+ <link rel="apple-touch-icon-precomposed" href="/assets/ico/apple-touch-icon-57-precomposed.png">
36
+ </head>
37
+
38
+ <body>
39
+
40
+ <div class="navbar navbar-fixed-top">
41
+ <div class="navbar-inner">
42
+ <div class="container">
43
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
44
+ <span class="icon-bar"></span>
45
+ <span class="icon-bar"></span>
46
+ <span class="icon-bar"></span>
47
+ </a>
48
+ <a class="brand" href="#">YourApp</a>
49
+ <div class="nav-collapse">
50
+ <ul class="nav">
51
+ <li class="divider-vertical"></li>
52
+ <li id="index" ><a href="/">Home</a></li>
53
+ <% @models.each do |model| %>
54
+ <li id="<%=model.name.downcase%>" ><a href="/<%=model.name.downcase%>/"><%= model.name %></a></li>
55
+ <% end %>
56
+ </ul>
57
+ <ul class="nav pull-right">
58
+ <li class="divider-vertical"></li>
59
+ <li><a href="/login">Log<%%= session[:valid] ? "out" : "in"%></a></li>
60
+ </ul>
61
+ </div><!--/.nav-collapse -->
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="container">
67
+ <%% if ! @flash.nil? then %>
68
+ <span class="span9 offset1">
69
+ <%% @flash.each do |alert| %>
70
+ <div class="alert alert-<%%=alert[:level].downcase%>" style="margin:0px; margin-bottom:8px;">
71
+ <button class="close" data-dismiss="alert">x</button>
72
+ <strong><%%=alert[:level].capitalize%>!</strong> <%%=alert[:message]%>
73
+ </div>
74
+ <%% end %>
75
+ </span>
76
+ <%%end %>
77
+ <%%= yield %>
78
+ </div> <!-- /container -->
79
+
80
+ <!-- Le javascript
81
+ ================================================== -->
82
+ <!-- Placed at the end of the document so the pages load faster -->
83
+ <script src="/assets/bootstrap/js/bootstrap.min.js"></script>
84
+ </body>
85
+ </html>
86
+
@@ -0,0 +1,4 @@
1
+ before do
2
+ @active_page = request.path_info.split(/\//)[1]
3
+ @active_page = "index" if @active_page.nil?
4
+ end
@@ -0,0 +1,4 @@
1
+ get '/' do
2
+ erb :index
3
+ end
4
+
metadata CHANGED
@@ -1,65 +1,100 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: beds
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
4
5
  prerelease:
5
- version: 0.0.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - James Paterni
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2012-06-12 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: rspec
12
+ date: 2012-09-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: &2156320300 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2156320300
25
+ - !ruby/object:Gem::Dependency
26
+ name: rubyzip
27
+ requirement: &2156319800 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.9.9
33
+ type: :runtime
17
34
  prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
35
+ version_requirements: *2156319800
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &2156319380 !ruby/object:Gem::Requirement
19
39
  none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
24
44
  type: :development
25
- version_requirements: *id001
26
- description:
45
+ prerelease: false
46
+ version_requirements: *2156319380
47
+ description: Easily create Sinatra applications quikcly and easily by scaffolding
48
+ your models.
27
49
  email: james@ruby-code.com
28
- executables:
50
+ executables:
29
51
  - beds
30
52
  extensions: []
31
-
32
53
  extra_rdoc_files: []
33
-
34
- files:
35
- - lib/beds.rb
54
+ files:
55
+ - ./lib/beds.rb
56
+ - ./lib/cli.rb
57
+ - ./lib/new.rb
58
+ - ./lib/scaffold.rb
59
+ - ./templates/erb/edit.erb
60
+ - ./templates/erb/list.erb
61
+ - ./templates/erb/new.erb
62
+ - ./templates/hooks/bootstrap.rb
63
+ - ./templates/hooks/jquery.rb
64
+ - ./templates/routes/delete.erb
65
+ - ./templates/routes/edit.erb
66
+ - ./templates/routes/list.erb
67
+ - ./templates/routes/new.erb
68
+ - ./templates/routes/save.erb
69
+ - ./templates/static_erb/index.erb
70
+ - ./templates/static_erb/layout.erb
71
+ - ./templates/static_routes/before.erb
72
+ - ./templates/static_routes/index.erb
36
73
  - bin/beds
37
- homepage: https://github.com/jamez01/beds
74
+ homepage: http://github.com/jamez01/beds
38
75
  licenses: []
39
-
40
76
  post_install_message:
41
77
  rdoc_options: []
42
-
43
- require_paths:
78
+ require_paths:
44
79
  - lib
45
- required_ruby_version: !ruby/object:Gem::Requirement
80
+ required_ruby_version: !ruby/object:Gem::Requirement
46
81
  none: false
47
- requirements:
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: "0"
51
- required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
87
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: "0"
57
- requirements: []
58
-
59
- rubyforge_project: nowarning
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements:
93
+ - sinatra, version 1.3.3
94
+ - rubyzip, version 0.9.9
95
+ rubyforge_project:
60
96
  rubygems_version: 1.8.15
61
97
  signing_key:
62
98
  specification_version: 3
63
99
  summary: The BootStrap ERb DataMapper Sinatra [scaffolder]
64
100
  test_files: []
65
-