metajp 0.1.0
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/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +59 -0
- data/lib/metajp/shared/super_crud/controller.rb +160 -0
- data/lib/metajp/shared/super_crud/helper.rb +120 -0
- data/lib/metajp/shared/super_crud/model.rb +0 -0
- data/lib/metajp/templates/admin.rb +0 -0
- data/lib/metajp/templates/authlogic.rb +45 -0
- data/lib/metajp/templates/base.rb +38 -0
- data/lib/metajp/templates/capistrano.rb +13 -0
- data/lib/metajp/templates/config/deploy.rb +37 -0
- data/lib/metajp/templates/controllers/admin/admin_controller.rb +21 -0
- data/lib/metajp/templates/controllers/user_sessions_controller.rb +30 -0
- data/lib/metajp/templates/controllers/users/activations_controller.rb +0 -0
- data/lib/metajp/templates/controllers/users/password_resets_controller.rb +49 -0
- data/lib/metajp/templates/git.rb +18 -0
- data/lib/metajp/templates/models/notifier.rb +28 -0
- data/lib/metajp/templates/models/user.rb +58 -0
- data/lib/metajp/templates/public/javascripts/application.js +0 -0
- data/lib/metajp/templates/public/stylesheets/application.css +0 -0
- data/lib/metajp/templates/rspec.rb +5 -0
- data/lib/metajp/templates/setup.rb +0 -0
- data/lib/metajp/templates/views/admin.html.erb +29 -0
- data/lib/metajp/templates/views/application.html.erb +0 -0
- data/lib/metajp.rb +38 -0
- data/test/helper.rb +10 -0
- data/test/test_metajp.rb +7 -0
- metadata +85 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 John Paul Narowski
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
= metajp
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but
|
13
|
+
bump version in a commit by itself I can ignore when I pull)
|
14
|
+
* Send me a pull request. Bonus points for topic branches.
|
15
|
+
|
16
|
+
== Copyright
|
17
|
+
|
18
|
+
Copyright (c) 2010 John Paul Narowski. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "metajp"
|
8
|
+
gem.summary = %Q{Shared functionality for rails apps}
|
9
|
+
gem.description = %Q{These tools help setup and install plugins}
|
10
|
+
gem.email = "jnarowski@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/jnarowski/metajp"
|
12
|
+
gem.authors = ["John Paul Narowski"]
|
13
|
+
gem.files = [
|
14
|
+
".document",
|
15
|
+
".gitignore",
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc",
|
18
|
+
"Rakefile",
|
19
|
+
Dir["{test,lib}/**/*"],
|
20
|
+
"test/helper.rb",
|
21
|
+
"test/test_metastrano.rb"
|
22
|
+
]
|
23
|
+
end
|
24
|
+
rescue LoadError
|
25
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
26
|
+
end
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |test|
|
38
|
+
test.libs << 'test'
|
39
|
+
test.pattern = 'test/**/test_*.rb'
|
40
|
+
test.verbose = true
|
41
|
+
end
|
42
|
+
rescue LoadError
|
43
|
+
task :rcov do
|
44
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
task :test => :check_dependencies
|
49
|
+
task :default => :test
|
50
|
+
|
51
|
+
require 'rake/rdoctask'
|
52
|
+
Rake::RDocTask.new do |rdoc|
|
53
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
54
|
+
|
55
|
+
rdoc.rdoc_dir = 'rdoc'
|
56
|
+
rdoc.title = "metajp #{version}"
|
57
|
+
rdoc.rdoc_files.include('README*')
|
58
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
59
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Metajp
|
2
|
+
module Shared
|
3
|
+
module SuperCrud
|
4
|
+
module Controller
|
5
|
+
|
6
|
+
#----------------------------------------------------------------
|
7
|
+
# controller functionality
|
8
|
+
# -- you can override or extend if you want
|
9
|
+
#----------------------------------------------------------------
|
10
|
+
|
11
|
+
def display_list
|
12
|
+
load_params
|
13
|
+
load_objects
|
14
|
+
update_list
|
15
|
+
end
|
16
|
+
|
17
|
+
def index
|
18
|
+
load_params
|
19
|
+
load_objects
|
20
|
+
end
|
21
|
+
|
22
|
+
def edit
|
23
|
+
respond_to do |format|
|
24
|
+
format.html # edit.html
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def show
|
29
|
+
load_object
|
30
|
+
end
|
31
|
+
|
32
|
+
#----------------------------------------------------------------
|
33
|
+
# CRUD helper methods
|
34
|
+
#----------------------------------------------------------------
|
35
|
+
|
36
|
+
def _create(object, path = nil)
|
37
|
+
respond_to do |format|
|
38
|
+
if object.save
|
39
|
+
load_objects
|
40
|
+
flash[:notice] = "#{@_name} was successfully created."
|
41
|
+
format.html { redirect_to(set_path(object, path)) }
|
42
|
+
else
|
43
|
+
format.html { render :action => "new" }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def _update(object, path = nil)
|
49
|
+
respond_to do |format|
|
50
|
+
if object.update_attributes(@_attributes)
|
51
|
+
flash[:notice] = "#{@_name} was successfully updated."
|
52
|
+
format.html { redirect_to(set_path(object, path)) }
|
53
|
+
else
|
54
|
+
format.html { render :action => "edit" }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def _destroy(name, object, object_name)
|
60
|
+
object.destroy
|
61
|
+
respond_to do |format|
|
62
|
+
format.js { simple_destroy(name, object, :message => "#{object_name} has been removed.") }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#----------------------------------------------------------------
|
67
|
+
# helper functions
|
68
|
+
#----------------------------------------------------------------
|
69
|
+
|
70
|
+
# used to set the path in the #_update and #_create methods
|
71
|
+
def set_path(object, path)
|
72
|
+
path.blank? ? "#{@_path}/#{object.id}" : path
|
73
|
+
end
|
74
|
+
|
75
|
+
# if the user has searched, add the search filter parameter
|
76
|
+
# this will pop the box in the top of the table listing
|
77
|
+
def add_search_if_present(collections)
|
78
|
+
if params[:search]
|
79
|
+
@filter_text = "Search for '#{params[:search]}'"
|
80
|
+
collections.search(params[:search])
|
81
|
+
else
|
82
|
+
collections
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# This is used to add extra parameters to the column_heading and pagination filtering
|
87
|
+
# in the controller if you wanted to add the params[:search] to the filters
|
88
|
+
# EG: add_extra_param(:search)
|
89
|
+
#
|
90
|
+
def add_filter_param(name)
|
91
|
+
@extra_params[name] = params[name] unless params[name].blank?
|
92
|
+
end
|
93
|
+
|
94
|
+
#----------------------------------------------------------------
|
95
|
+
# searching and sorting helpers
|
96
|
+
#----------------------------------------------------------------
|
97
|
+
|
98
|
+
def get_order(ordering, exact = false)
|
99
|
+
if ordering
|
100
|
+
order_array = ordering.split("_")
|
101
|
+
direction = (order_array[0] == 'ascend') ? 'ASC' : 'DESC'
|
102
|
+
column = ''
|
103
|
+
order_array.each_with_index {|a, index| column += "#{a}_" if index > 1}
|
104
|
+
column = column[0..-2]
|
105
|
+
"#{column} #{direction}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
#----------------------------------------------------------------
|
110
|
+
# shared rjs methods
|
111
|
+
#----------------------------------------------------------------
|
112
|
+
|
113
|
+
def update_list(options = {})
|
114
|
+
options[:sidebar] = 'side_menu'
|
115
|
+
render :update do |page|
|
116
|
+
page.replace_html 'list', :partial => 'list'
|
117
|
+
page.replace_html 'side-menu', :partial => options[:sidebar] if options[:reload_sidebar]
|
118
|
+
page.replace_html options[:reload_partial], :partial => options[:reload_partial] if options[:reload_partial]
|
119
|
+
# show the advanced filter text
|
120
|
+
unless @filter_text.blank?
|
121
|
+
page.replace_html 'filter', filter_results
|
122
|
+
page.show "filter"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def simple_destroy(id, object, options = {})
|
128
|
+
dom_id = options[:id] ? options[:id] : "#{id}-#{object.id}"
|
129
|
+
render :update do |page|
|
130
|
+
page.remove dom_id
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
#----------------------------------------------------------------
|
135
|
+
# private functionaltiy
|
136
|
+
#----------------------------------------------------------------
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
# this loads params for the index page
|
141
|
+
# sets defaults for column sorting, searching etc
|
142
|
+
def load_params
|
143
|
+
super
|
144
|
+
@extra_params = {}
|
145
|
+
@ordering ||= 'descend_by_created_at'
|
146
|
+
add_filter_param(:search)
|
147
|
+
end
|
148
|
+
|
149
|
+
# sets page default options, selected tab states ETC
|
150
|
+
def initialize_page
|
151
|
+
super
|
152
|
+
action = action_name == 'index' ? "#{@_name}s" : "#{action_name.capitalize} #{@_name}"
|
153
|
+
@page_title = action
|
154
|
+
@render_options[:selected_tab] = @_selected_tab
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Metajp
|
2
|
+
module Shared
|
3
|
+
module SuperCrud
|
4
|
+
module Helper
|
5
|
+
|
6
|
+
#----------------------------------------------------------------
|
7
|
+
# framework stuff
|
8
|
+
#----------------------------------------------------------------
|
9
|
+
|
10
|
+
def filter_results
|
11
|
+
out = ""
|
12
|
+
out += "<div id=\"filter-results-count\" class=\"float-right\">#{@filter_count} found #{link_to(super_icon('cross'), {:controller => controller_name})}</div>" if @filter_count
|
13
|
+
out += "<div id=\"filter-results\">#{@filter_text}</div>#{}" if @filter_text
|
14
|
+
out
|
15
|
+
end
|
16
|
+
|
17
|
+
def super_header(name, &block)
|
18
|
+
heading = "<h1>#{name}</h1>"
|
19
|
+
concat("<div id='sub-header'>#{capture(&block)}#{heading}#{float_clear}</div>")
|
20
|
+
end
|
21
|
+
|
22
|
+
def super_table(&block)
|
23
|
+
table_start = '<div id="filter" class="rounded" style="display: none;"></div>
|
24
|
+
<table class="stripped-list list" cellspacing="0" width="750px">'
|
25
|
+
concat("#{table_start}#{capture(&block)}</table>")
|
26
|
+
end
|
27
|
+
|
28
|
+
def super_row(name, object, iterator = nil, &block)
|
29
|
+
line = (iterator ? iterator % 2 : 0)
|
30
|
+
concat("<tr id='#{name}-#{object.id}' class='line-#{line} padded-td'>#{capture(&block)}</tr>")
|
31
|
+
end
|
32
|
+
|
33
|
+
def super_paginate(collection)
|
34
|
+
"<div id='table-footer'>#{super_custom_remote_paginate(collection)}</div>"
|
35
|
+
end
|
36
|
+
|
37
|
+
# table header
|
38
|
+
def table_header(width, name, column, options = {})
|
39
|
+
filler = options[:plain_text].blank? ? super_column_heading(name, column) : name
|
40
|
+
"<th width='#{width}' class='#{options[:class]}'>#{filler}</th>"
|
41
|
+
end
|
42
|
+
|
43
|
+
def super_button(name, link, options = {})
|
44
|
+
div_style = options.delete(:div_style)
|
45
|
+
"<div class='button' style='#{div_style}'>#{link_to(name, link, options)}</div>"
|
46
|
+
end
|
47
|
+
|
48
|
+
def super_menu_item(name, link, selected = nil, options = {})
|
49
|
+
options[:class] = 'selected' if selected == @render_options[:selected_tab] && !@render_options[:selected_tab].blank?
|
50
|
+
"<li>#{link_to(name, link, options)}</li>"
|
51
|
+
end
|
52
|
+
|
53
|
+
#----------------------------------------------------------------
|
54
|
+
# general helpers
|
55
|
+
#----------------------------------------------------------------
|
56
|
+
|
57
|
+
def set_admin_url(object, path)
|
58
|
+
object.new_record? ? "/admin/#{path}/" : "/admin/#{path}/#{object.id}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def super_icon(type, options = {})
|
62
|
+
width = 16
|
63
|
+
alt = nil
|
64
|
+
file_name = "#{type}.png"
|
65
|
+
"<img src=\"/images/icons/#{file_name}\" alt=\"#{alt ? alt : type}\" #{"title=\"#{alt}\"" if !alt.blank?} style=\"width: #{width}px;\" />"
|
66
|
+
end
|
67
|
+
|
68
|
+
#----------------------------------------------------------------
|
69
|
+
# show helpers
|
70
|
+
#----------------------------------------------------------------
|
71
|
+
|
72
|
+
def super_show_item(name, value)
|
73
|
+
value = value.blank? ? '<i>null</i>' : value
|
74
|
+
"<p>
|
75
|
+
<label class='strong'>#{name}</label>
|
76
|
+
#{value}
|
77
|
+
</p>"
|
78
|
+
end
|
79
|
+
|
80
|
+
#----------------------------------------------------------------
|
81
|
+
# table sorting and filtering helpers
|
82
|
+
#----------------------------------------------------------------
|
83
|
+
|
84
|
+
def super_column_heading(display_name, attribute, controller = controller_name)
|
85
|
+
options = {
|
86
|
+
:controller => controller,
|
87
|
+
:action => 'display_list',
|
88
|
+
:ordering => ordering(attribute),
|
89
|
+
:attribute => attribute.to_s
|
90
|
+
}.merge!(@extra_params)
|
91
|
+
link_to("#{display_name} #{super_triangle(attribute)}", options, :class => 'column-header')
|
92
|
+
end
|
93
|
+
|
94
|
+
def super_custom_remote_paginate(collection, options = {})
|
95
|
+
options[:ordering] ||= @ordering
|
96
|
+
options[:attribute] ||= @attribute
|
97
|
+
options[:controller] ||= controller_name
|
98
|
+
options[:action] ||= 'display_list'
|
99
|
+
options[:method] ||= 'post'
|
100
|
+
options.merge!(@extra_params)
|
101
|
+
"<div class='pagination'>#{will_paginate(collection, :params => options, :remote => {})}</div>#{float_clear}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def super_triangle(attribute)
|
105
|
+
return "▲" if @ordering == "ascend_by_#{attribute}"
|
106
|
+
return "▼" if @ordering == "descend_by_#{attribute}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def ordering(attribute)
|
110
|
+
if @ordering == "ascend_by_#{attribute}" then
|
111
|
+
"descend_by_#{attribute}"
|
112
|
+
else
|
113
|
+
"ascend_by_#{attribute}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'metajp'
|
2
|
+
@template ||= Metajp.get_template_path
|
3
|
+
|
4
|
+
if yes?("Do you want to add authlogic to this project?")
|
5
|
+
gem 'authlogic'
|
6
|
+
|
7
|
+
# user sessions
|
8
|
+
generate(:session, "user_session")
|
9
|
+
generate(:controller, "user_sessions")
|
10
|
+
run "cp #{@template}/controllers/user_sessions_controller.rb app/controllers/user_sessions_controller.rb"
|
11
|
+
|
12
|
+
# create the model
|
13
|
+
generate(:model, "user", "first_name:string", "last_name:string", "email:string", "crypted_password:string", "password_salt:string", "persistence_token:string", "perishable_token:string")
|
14
|
+
run "cp #{@template}/models/user.rb app/models/user.rb"
|
15
|
+
|
16
|
+
# user_session routes
|
17
|
+
route "map.login 'login', :controller => 'user_sessions', :action => 'new'"
|
18
|
+
route "map.login 'logout', :controller => 'user_sessions', :action => 'destroy'"
|
19
|
+
route "map.resources :user_sessions"
|
20
|
+
route "map.resources :users"
|
21
|
+
|
22
|
+
if yes?("Do you want to add user activation and password reset?")
|
23
|
+
|
24
|
+
# account routes
|
25
|
+
route "map.login '/login', :controller => :user_sessions, :action => :new"
|
26
|
+
route "map.logout '/logout', :controller => :user_sessions, :action => :destroy"
|
27
|
+
route "map.account '/account', :controller => :users, :action => :show"
|
28
|
+
route "map.edit_account '/account/edit', :controller => :users, :action => :edit"
|
29
|
+
|
30
|
+
route "map.resources :password_resets, :path_prefix => 'account', :controller => 'account/password_resets'"
|
31
|
+
|
32
|
+
# account activation
|
33
|
+
route "map.register '/register/:perishable_token', :controller => 'account/activations', :action => 'new'"
|
34
|
+
route "map.activate '/activate/:id', :controller => 'account/activations', :action => 'create'"
|
35
|
+
route "map.signup '/signup', :controller => 'users', :action => 'new'"
|
36
|
+
|
37
|
+
# account password reset
|
38
|
+
route "map.forgot_password '/account/forgot-password', :controller => 'account/password_resets', :action => 'new'"
|
39
|
+
route "map.change_password '/account/change-password/:perishable_token', :controller => 'account/password_resets', :action => 'edit'"
|
40
|
+
route "map.reset_password '/account/reset-password/:perishable_token', :controller => 'account/password_resets', :action => 'update'"
|
41
|
+
end
|
42
|
+
|
43
|
+
rake "db:migrate" unless @base
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'metajp'
|
2
|
+
|
3
|
+
# setup variables
|
4
|
+
app_name = ask("What do you want your app to be called?")
|
5
|
+
@template = Metajp.get_template_path
|
6
|
+
@base = true
|
7
|
+
|
8
|
+
# install plugins
|
9
|
+
plugin "asset_packager", :git => "git://github.com/sbecker/asset_packager.git"
|
10
|
+
plugin "jrails", :git => "git://github.com/aaronchi/jrails.git"
|
11
|
+
plugin "paperclip", :git => "git://github.com/thoughtbot/paperclip.git"
|
12
|
+
|
13
|
+
# install base gems
|
14
|
+
gem 'will_paginate', :version => '~> 2.2.2'
|
15
|
+
gem 'whenever' if yes?("Do you want to add cronjobs to this app?")
|
16
|
+
|
17
|
+
# cleanup files
|
18
|
+
run 'rm README'
|
19
|
+
run 'rm public/index.html'
|
20
|
+
run 'rm public/favicon.ico'
|
21
|
+
run 'rm public/images/rails.png'
|
22
|
+
run "rm public/robots.txt"
|
23
|
+
run "rm -f public/javascripts/*"
|
24
|
+
|
25
|
+
# load additional options from templates
|
26
|
+
load_template(@template + "/rspec.rb")
|
27
|
+
load_template(@template + "/git.rb")
|
28
|
+
load_template(@template + "/authlogic.rb")
|
29
|
+
load_template(@template + "/capistrano.rb")
|
30
|
+
|
31
|
+
# install the gems
|
32
|
+
rake "gems:install", :sudo => true
|
33
|
+
|
34
|
+
# create and migrate the database
|
35
|
+
run "mysqladmin -u root create #{app_name.downcase.gsub(" ", '')}_dev"
|
36
|
+
run "mysqladmin -u root create #{app_name.downcase.gsub(" ", '')}_test"
|
37
|
+
rake "db:migrate"
|
38
|
+
rake "db:test:clone"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
if yes?("Do you want to add capistrano?")
|
2
|
+
|
3
|
+
capify!
|
4
|
+
|
5
|
+
file 'Capfile', <<-FILE
|
6
|
+
require 'metastrano'
|
7
|
+
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
|
8
|
+
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
|
9
|
+
load 'config/deploy'
|
10
|
+
FILE
|
11
|
+
|
12
|
+
#file 'config/deploy.rb',
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# required
|
2
|
+
set :application, "application name"
|
3
|
+
set :deploy_to, "/var/www/rails/#{application}"
|
4
|
+
set :domain, "metajp.com"
|
5
|
+
set :repository, "#{scm_username}@#{domain}:#{application}.git"
|
6
|
+
|
7
|
+
# extra options
|
8
|
+
default_run_options[:pty] = true
|
9
|
+
set :use_sudo, false
|
10
|
+
set :shared_children, %w(system log pids config)
|
11
|
+
set :rails_env, 'production'
|
12
|
+
|
13
|
+
# defaults
|
14
|
+
role :app, domain
|
15
|
+
role :web, domain
|
16
|
+
role :db, domain, :primary => true
|
17
|
+
|
18
|
+
#----------------------------------------------------------------
|
19
|
+
# hooks to setup all the fun
|
20
|
+
#----------------------------------------------------------------
|
21
|
+
|
22
|
+
namespace :deploy do
|
23
|
+
task :start do; end
|
24
|
+
task :stop do; end
|
25
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
26
|
+
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
after "deploy:setup" do
|
31
|
+
db.mysql.setup if Capistrano::CLI.ui.agree("Do you want to create the database, user, and config/database.yml file?")
|
32
|
+
apache.create_vhost if Capistrano::CLI.ui.agree("Do you want to create the apache virtual host file?")
|
33
|
+
end
|
34
|
+
|
35
|
+
after "deploy:symlink", "db:mysql:symlink"
|
36
|
+
after "deploy:update_code", "rake:rebuild_assets"
|
37
|
+
after "deploy:symlink", "deploy:update_crontab"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Users::ActivationsController < ApplicationController
|
2
|
+
before_filter :require_no_user, :only => [:new, :create]
|
3
|
+
|
4
|
+
def new
|
5
|
+
@user = User.find_using_perishable_token(params[:perishable_token], 1.week) || (raise Exception)
|
6
|
+
raise Exception if @user.active?
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@user = User.find(params[:id])
|
11
|
+
raise Exception if @user.active?
|
12
|
+
if @user.activate!(params)
|
13
|
+
@user.deliver_activation_confirmation!
|
14
|
+
flash[:notice] = "Your account has been activated."
|
15
|
+
redirect_to account_url
|
16
|
+
else
|
17
|
+
render :action => :new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class UserSessionsController < ApplicationController
|
2
|
+
layout 'application'
|
3
|
+
|
4
|
+
before_filter :require_no_user, :only => [:new, :create]
|
5
|
+
before_filter :require_user, :only => :destroy
|
6
|
+
|
7
|
+
def new
|
8
|
+
@user_session = UserSession.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
@user_session = UserSession.new(params[:user_session])
|
13
|
+
if @user_session.save
|
14
|
+
flash[:success] = "Login successful!"
|
15
|
+
if @user_session.user.login_count == 1
|
16
|
+
redirect_to :controller => :users, :action => :edit
|
17
|
+
else
|
18
|
+
redirect_to :controller => :dashboard
|
19
|
+
end
|
20
|
+
else
|
21
|
+
render :action => :new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
current_user_session.destroy
|
27
|
+
flash[:notice] = "Logout successful!"
|
28
|
+
redirect_to :controller => :user_sessions, :action => :new
|
29
|
+
end
|
30
|
+
end
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Users::PasswordResetsController < ApplicationController
|
2
|
+
before_filter :load_user_using_perishable_token, :only => [:edit, :update]
|
3
|
+
before_filter :require_no_user
|
4
|
+
|
5
|
+
def new
|
6
|
+
render
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@user = User.find_by_email(params[:email])
|
11
|
+
if @user
|
12
|
+
@user.deliver_password_reset_instructions!
|
13
|
+
flash[:notice] = "Instructions to reset your password have been emailed to you. Please check your email."
|
14
|
+
redirect_to root_url
|
15
|
+
else
|
16
|
+
flash[:notice] = "No user was found with that email address"
|
17
|
+
render :action => :new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def edit
|
22
|
+
render
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@user.password = params[:user][:password]
|
27
|
+
@user.password_confirmation = params[:user][:password_confirmation]
|
28
|
+
if @user.save
|
29
|
+
@user.reset_perishable_token!
|
30
|
+
flash[:notice] = "Password successfully updated"
|
31
|
+
redirect_to account_url
|
32
|
+
else
|
33
|
+
render :action => :edit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def load_user_using_perishable_token
|
40
|
+
@user = User.find_using_perishable_token(params[:perishable_token])
|
41
|
+
unless @user
|
42
|
+
flash[:notice] = "We're sorry, but we could not locate your account. " +
|
43
|
+
"If you are having issues try copying and pasting the URL " +
|
44
|
+
"from your email into your browser or restarting the " +
|
45
|
+
"reset password process."
|
46
|
+
redirect_to root_url
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
if yes?("Do you want to add this project to git?")
|
2
|
+
git :init
|
3
|
+
|
4
|
+
file ".gitignore", <<-END
|
5
|
+
.DS_Store
|
6
|
+
log/*.log
|
7
|
+
tmp/**/*
|
8
|
+
config/database.yml
|
9
|
+
db/*.sqlite3
|
10
|
+
END
|
11
|
+
|
12
|
+
run "touch tmp/.gitignore log/.gitignore vendor/.gitignore"
|
13
|
+
run "cp config/database.yml config/example_database.yml"
|
14
|
+
|
15
|
+
git :rm => "public/index.html"
|
16
|
+
git :add => "."
|
17
|
+
git :commit => "-m 'initial commit'"
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Notifier < ActionMailer::Base
|
2
|
+
default_url_options[:host] = 'localhost:3000'
|
3
|
+
|
4
|
+
def activation_instructions(user)
|
5
|
+
subject "Activation Instructions"
|
6
|
+
from "petit vogue <user-activation@petitvogue.com>"
|
7
|
+
recipients user.email
|
8
|
+
sent_on Time.now
|
9
|
+
body :account_activation_url => register_url(user.perishable_token)
|
10
|
+
end
|
11
|
+
|
12
|
+
def activation_confirmation(user)
|
13
|
+
subject "Activation Complete"
|
14
|
+
from "petit vogue <user-activation@petitvogue.com>"
|
15
|
+
recipients user.email
|
16
|
+
sent_on Time.now
|
17
|
+
body :root_url => root_url
|
18
|
+
end
|
19
|
+
|
20
|
+
def password_reset_instructions(user)
|
21
|
+
subject "Password Reset Instructions"
|
22
|
+
from "petit vogue <noreply@petitvogue.com>"
|
23
|
+
recipients user.email
|
24
|
+
sent_on Time.now
|
25
|
+
body :reset_password_url => change_password_url(user.perishable_token)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
acts_as_authentic
|
3
|
+
|
4
|
+
#----------------------------------------------------------------
|
5
|
+
# account general
|
6
|
+
#----------------------------------------------------------------
|
7
|
+
|
8
|
+
def generate_temporary_password!
|
9
|
+
chars = ("a".."z").to_a + ("1".."9").to_a
|
10
|
+
temp_pass = Array.new(8, '').collect{chars[rand(chars.size)]}.join
|
11
|
+
self.password = temp_pass
|
12
|
+
self.password_confirmation = temp_pass
|
13
|
+
end
|
14
|
+
|
15
|
+
#----------------------------------------------------------------
|
16
|
+
# account activation
|
17
|
+
#----------------------------------------------------------------
|
18
|
+
|
19
|
+
# now let's define a couple of methods in the user model. The first
|
20
|
+
# will take care of setting any data that you want to happen at signup
|
21
|
+
# (aka before activation)
|
22
|
+
def signup!(params)
|
23
|
+
self.login = params[:user][:login]
|
24
|
+
self.email = params[:user][:email]
|
25
|
+
generate_temporary_password!
|
26
|
+
save_without_session_maintenance
|
27
|
+
end
|
28
|
+
|
29
|
+
# the second will take care of setting any data that you want to happen
|
30
|
+
# at activation. at the very least this will be setting active to true
|
31
|
+
# and setting a pass, openid, or both.
|
32
|
+
def activate!(params)
|
33
|
+
self.active = true
|
34
|
+
self.password = params[:user][:password]
|
35
|
+
self.password_confirmation = params[:user][:password_confirmation]
|
36
|
+
save
|
37
|
+
end
|
38
|
+
|
39
|
+
def deliver_activation_instructions!
|
40
|
+
reset_perishable_token!
|
41
|
+
Notifier.deliver_activation_instructions(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
def deliver_activation_confirmation!
|
45
|
+
reset_perishable_token!
|
46
|
+
Notifier.deliver_activation_confirmation(self)
|
47
|
+
end
|
48
|
+
|
49
|
+
#----------------------------------------------------------------
|
50
|
+
# password reset
|
51
|
+
#----------------------------------------------------------------
|
52
|
+
|
53
|
+
def deliver_password_reset_instructions!
|
54
|
+
reset_perishable_token!
|
55
|
+
Notifier.deliver_password_reset_instructions(self)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
6
|
+
<title><%= @page_title + " | " if @page_title && !@page_title.blank? %> Admin</title>
|
7
|
+
<%= stylesheet_link_merged :base %>
|
8
|
+
<%= stylesheet_link_tag 'admin.css' %>
|
9
|
+
|
10
|
+
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js' %>
|
11
|
+
<%= javascript_include_merged :base %>
|
12
|
+
<%= javascript_include_tag 'admin.js' %>
|
13
|
+
</head>
|
14
|
+
|
15
|
+
<body>
|
16
|
+
<div id="header">
|
17
|
+
<div class="wrapper">
|
18
|
+
<div class="float-right"><%= link_to 'Logout', '/logout' %></div>
|
19
|
+
<ul class="nav">
|
20
|
+
<%= super_menu_item 'Test', '/admin/test' %>
|
21
|
+
</ul>
|
22
|
+
<%= float_clear %>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
<div class="wrapper">
|
26
|
+
<%= yield %>
|
27
|
+
</div>
|
28
|
+
</body>
|
29
|
+
</html>
|
File without changes
|
data/lib/metajp.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.dirname(__FILE__) + '/metajp/shared/super_crud/controller.rb'
|
3
|
+
require File.dirname(__FILE__) + '/metajp/shared/super_crud/model.rb'
|
4
|
+
require File.dirname(__FILE__) + '/metajp/shared/super_crud/helper.rb'
|
5
|
+
|
6
|
+
module Metajp
|
7
|
+
|
8
|
+
VERSION = '0.1.0'
|
9
|
+
|
10
|
+
#----------------------------------------------------------------
|
11
|
+
# extensions for the controller
|
12
|
+
#----------------------------------------------------------------
|
13
|
+
|
14
|
+
module Controller
|
15
|
+
def self.included(base)
|
16
|
+
base.send :extend, ClassMethods
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def super_controller
|
21
|
+
send :include, Metajp::Shared::SuperCrud::Controller
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.get_template_path
|
27
|
+
Gem.path.each do |path|
|
28
|
+
tmp_path = "#{path}/gems/metajp-#{VERSION}"
|
29
|
+
return "#{tmp_path}/lib/metajp/templates" if File.exists?(tmp_path)
|
30
|
+
end
|
31
|
+
raise "Cannot find gem 'metajp-#{VERSION}' on your system" unless @template
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
if defined?(Rails) && defined?(ActionController)
|
37
|
+
ActionController::Base.send :include, Metajp::Controller
|
38
|
+
end
|
data/test/helper.rb
ADDED
data/test/test_metajp.rb
ADDED
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: metajp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Paul Narowski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-27 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: These tools help setup and install plugins
|
17
|
+
email: jnarowski@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- lib/metajp.rb
|
32
|
+
- lib/metajp/shared/super_crud/controller.rb
|
33
|
+
- lib/metajp/shared/super_crud/helper.rb
|
34
|
+
- lib/metajp/shared/super_crud/model.rb
|
35
|
+
- lib/metajp/templates/admin.rb
|
36
|
+
- lib/metajp/templates/authlogic.rb
|
37
|
+
- lib/metajp/templates/base.rb
|
38
|
+
- lib/metajp/templates/capistrano.rb
|
39
|
+
- lib/metajp/templates/config/deploy.rb
|
40
|
+
- lib/metajp/templates/controllers/admin/admin_controller.rb
|
41
|
+
- lib/metajp/templates/controllers/user_sessions_controller.rb
|
42
|
+
- lib/metajp/templates/controllers/users/activations_controller.rb
|
43
|
+
- lib/metajp/templates/controllers/users/password_resets_controller.rb
|
44
|
+
- lib/metajp/templates/git.rb
|
45
|
+
- lib/metajp/templates/models/notifier.rb
|
46
|
+
- lib/metajp/templates/models/user.rb
|
47
|
+
- lib/metajp/templates/public/javascripts/application.js
|
48
|
+
- lib/metajp/templates/public/stylesheets/application.css
|
49
|
+
- lib/metajp/templates/rspec.rb
|
50
|
+
- lib/metajp/templates/setup.rb
|
51
|
+
- lib/metajp/templates/views/admin.html.erb
|
52
|
+
- lib/metajp/templates/views/application.html.erb
|
53
|
+
- test/helper.rb
|
54
|
+
- test/test_metajp.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/jnarowski/metajp
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --charset=UTF-8
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.3.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Shared functionality for rails apps
|
83
|
+
test_files:
|
84
|
+
- test/helper.rb
|
85
|
+
- test/test_metajp.rb
|