beds 0.0.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.
Files changed (3) hide show
  1. data/bin/beds +70 -0
  2. data/lib/beds.rb +298 -0
  3. metadata +65 -0
data/bin/beds ADDED
@@ -0,0 +1,70 @@
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"
54
+ else
55
+ File.open(@options[:routefile],"w") {|file| file.write(scaffold.routes.join("\n"))}
56
+ end
57
+
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
+
70
+ puts "Generated files: #{@gen_files.join(", ")}"
data/lib/beds.rb ADDED
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env ruby
2
+ require 'erb'
3
+ require 'optparse'
4
+
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?
11
+ end
12
+ ^,
13
+ :index => %Q^
14
+ get '/' do
15
+ erb :index
16
+ 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 -->
30
+
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
298
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beds
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - James Paterni
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-06-12 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ description:
27
+ email: james@ruby-code.com
28
+ executables:
29
+ - beds
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - lib/beds.rb
36
+ - bin/beds
37
+ homepage: https://github.com/jamez01/beds
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project: nowarning
60
+ rubygems_version: 1.8.15
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: The BootStrap ERb DataMapper Sinatra [scaffolder]
64
+ test_files: []
65
+