parlement 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +709 -0
- data/COPYING +223 -0
- data/README +20 -0
- data/Rakefile +136 -0
- data/app/controllers/account_controller.rb +181 -0
- data/app/controllers/application.rb +30 -0
- data/app/controllers/elt_controller.rb +83 -0
- data/app/helpers/account_helper.rb +2 -0
- data/app/helpers/application_helper.rb +4 -0
- data/app/helpers/elt_helper.rb +37 -0
- data/app/helpers/live_tree.rb +238 -0
- data/app/helpers/mailman.rb +96 -0
- data/app/models/attachment.rb +4 -0
- data/app/models/elt.rb +17 -0
- data/app/models/mail.rb +4 -0
- data/app/models/notifier.rb +13 -0
- data/app/models/person.rb +9 -0
- data/app/models/user.rb +7 -0
- data/app/models/user_notify.rb +75 -0
- data/app/views/account/_help.rhtml +23 -0
- data/app/views/account/_login.rhtml +57 -0
- data/app/views/account/_show.rhtml +31 -0
- data/app/views/account/logout.rhtml +10 -0
- data/app/views/account/signup.rhtml +17 -0
- data/app/views/account/welcome.rhtml +13 -0
- data/app/views/elt/_elt.rhtml +105 -0
- data/app/views/elt/_form.rhtml +31 -0
- data/app/views/elt/_list.rhtml +28 -0
- data/app/views/elt/new.rhtml +102 -0
- data/app/views/elt/rss.rxml +31 -0
- data/app/views/elt/show.rhtml +46 -0
- data/app/views/elt/show_tree.rhtml +8 -0
- data/app/views/layouts/scaffold.rhtml +13 -0
- data/app/views/layouts/top.rhtml +45 -0
- data/app/views/notifier/changeEmail.rhtml +10 -0
- data/config/boot.rb +17 -0
- data/config/database.yml +82 -0
- data/config/environment.rb +92 -0
- data/config/environments/development.rb +17 -0
- data/config/environments/production.rb +17 -0
- data/config/environments/test.rb +17 -0
- data/config/environments/user_environment.rb +1 -0
- data/config/routes.rb +28 -0
- data/db/ROOT/CV.txt +166 -0
- data/db/ROOT/IP.txt +3 -0
- data/db/ROOT/parleR.txt +3 -0
- data/db/ROOT/parlement/security.txt +34 -0
- data/db/ROOT/parlement/test.txt +4 -0
- data/db/ROOT/parlement.txt +51 -0
- data/db/ROOT/perso.txt +215 -0
- data/db/schema.sql +127 -0
- data/lib/data_import.rb +54 -0
- data/lib/file_column.rb +263 -0
- data/lib/file_column_helper.rb +45 -0
- data/lib/localization.rb +88 -0
- data/lib/localizer.rb +88 -0
- data/lib/login_system.rb +87 -0
- data/lib/rails_file_column.rb +19 -0
- data/lib/user_system.rb +101 -0
- data/public/404.html +8 -0
- data/public/500.html +8 -0
- data/public/dispatch.cgi +10 -0
- data/public/dispatch.fcgi +24 -0
- data/public/dispatch.rb +10 -0
- data/public/engine_files/README +5 -0
- data/public/engine_files/login_engine/stylesheets/login_engine.css +81 -0
- data/public/favicon.ico +0 -0
- data/public/favicon.png +0 -0
- data/public/images/live_tree_branch_collapsed_icon.gif +0 -0
- data/public/images/live_tree_branch_expanded_icon.gif +0 -0
- data/public/images/live_tree_leaf_icon.gif +0 -0
- data/public/images/live_tree_loading_spinner.gif +0 -0
- data/public/images/webfeed.gif +0 -0
- data/public/javascripts/controls.js +721 -0
- data/public/javascripts/dragdrop.js +519 -0
- data/public/javascripts/effects.js +992 -0
- data/public/javascripts/live_tree.js +749 -0
- data/public/javascripts/prototype.js +1726 -0
- data/public/javascripts/scriptaculous.js +47 -0
- data/public/javascripts/slider.js +258 -0
- data/public/oldREADME +190 -0
- data/public/oldindex.html +78 -0
- data/public/robots.txt +1 -0
- data/public/stylesheets/default.css +238 -0
- data/public/stylesheets/live_tree.css +62 -0
- data/public/stylesheets/scaffold.css +74 -0
- data/script/about +3 -0
- data/script/benchmarker +19 -0
- data/script/breakpointer +3 -0
- data/script/console +3 -0
- data/script/create_db +7 -0
- data/script/destroy +3 -0
- data/script/generate +3 -0
- data/script/performance/benchmarker +3 -0
- data/script/performance/profiler +3 -0
- data/script/plugin +3 -0
- data/script/process/reaper +3 -0
- data/script/process/spawner +3 -0
- data/script/process/spinner +3 -0
- data/script/profiler +34 -0
- data/script/runner +3 -0
- data/script/server +3 -0
- data/test/fixtures/attachments.yml +10 -0
- data/test/fixtures/elts.yml +15 -0
- data/test/fixtures/mails.yml +7 -0
- data/test/fixtures/people.yml +49 -0
- data/test/fixtures/users.yml +41 -0
- data/test/functional/account_controller_test.rb +239 -0
- data/test/functional/elt_controller_test.rb +18 -0
- data/test/mocks/test/time.rb +17 -0
- data/test/mocks/test/user_notify.rb +16 -0
- data/test/test_helper.rb +28 -0
- data/test/unit/attachment_test.rb +14 -0
- data/test/unit/elt_test.rb +14 -0
- data/test/unit/mail_test.rb +14 -0
- data/test/unit/notifier_test.rb +31 -0
- data/test/unit/person_test.rb +24 -0
- data/test/unit/user_test.rb +94 -0
- data/vendor/plugins/engines/CHANGELOG +7 -0
- data/vendor/plugins/engines/README +128 -0
- data/vendor/plugins/engines/init.rb +33 -0
- data/vendor/plugins/engines/lib/action_mailer_extensions.rb +160 -0
- data/vendor/plugins/engines/lib/action_view_extensions.rb +130 -0
- data/vendor/plugins/engines/lib/dependencies_extensions.rb +56 -0
- data/vendor/plugins/engines/lib/engines.rb +292 -0
- data/vendor/plugins/engines/lib/ruby_extensions.rb +127 -0
- data/vendor/plugins/engines/lib/testing_extensions.rb +33 -0
- data/vendor/plugins/engines/test/ruby_extensions_test.rb +94 -0
- data/vendor/plugins/login_engine/README +258 -0
- data/vendor/plugins/login_engine/app/controllers/user_controller.rb +248 -0
- data/vendor/plugins/login_engine/app/helpers/user_helper.rb +88 -0
- data/vendor/plugins/login_engine/app/models/user.rb +7 -0
- data/vendor/plugins/login_engine/app/models/user_notify.rb +75 -0
- data/vendor/plugins/login_engine/app/views/user/_edit.rhtml +11 -0
- data/vendor/plugins/login_engine/app/views/user/_password.rhtml +9 -0
- data/vendor/plugins/login_engine/app/views/user/change_password.rhtml +17 -0
- data/vendor/plugins/login_engine/app/views/user/edit.rhtml +23 -0
- data/vendor/plugins/login_engine/app/views/user/forgot_password.rhtml +18 -0
- data/vendor/plugins/login_engine/app/views/user/home.rhtml +7 -0
- data/vendor/plugins/login_engine/app/views/user/login.rhtml +17 -0
- data/vendor/plugins/login_engine/app/views/user/logout.rhtml +8 -0
- data/vendor/plugins/login_engine/app/views/user/signup.rhtml +17 -0
- data/vendor/plugins/login_engine/app/views/user_notify/change_password.rhtml +10 -0
- data/vendor/plugins/login_engine/app/views/user_notify/delete.rhtml +5 -0
- data/vendor/plugins/login_engine/app/views/user_notify/forgot_password.rhtml +11 -0
- data/vendor/plugins/login_engine/app/views/user_notify/pending_delete.rhtml +9 -0
- data/vendor/plugins/login_engine/app/views/user_notify/signup.rhtml +12 -0
- data/vendor/plugins/login_engine/db/schema.rb +25 -0
- data/vendor/plugins/login_engine/init_engine.rb +10 -0
- data/vendor/plugins/login_engine/lib/login_engine/authenticated_system.rb +107 -0
- data/vendor/plugins/login_engine/lib/login_engine/authenticated_user.rb +149 -0
- data/vendor/plugins/login_engine/lib/login_engine.rb +58 -0
- data/vendor/plugins/login_engine/public/stylesheets/login_engine.css +81 -0
- data/vendor/plugins/login_engine/tasks/tasks.rake +4 -0
- data/vendor/plugins/login_engine/test/fixtures/templates/users.yml +41 -0
- data/vendor/plugins/login_engine/test/fixtures/users.yml +41 -0
- data/vendor/plugins/login_engine/test/functional/user_controller_test.rb +533 -0
- data/vendor/plugins/login_engine/test/mocks/mail.rb +14 -0
- data/vendor/plugins/login_engine/test/mocks/time.rb +19 -0
- data/vendor/plugins/login_engine/test/test_helper.rb +15 -0
- data/vendor/plugins/login_engine/test/unit/user_test.rb +94 -0
- metadata +276 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005 James Adam
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
|
25
|
+
require 'engines'
|
26
|
+
|
27
|
+
#--
|
28
|
+
# Create the Engines directory if it isn't present
|
29
|
+
#++
|
30
|
+
if !File.exist?(Engines.config(:root))
|
31
|
+
RAILS_DEFAULT_LOGGER.debug "Creating engines directory in /vendor"
|
32
|
+
FileUtils.mkdir_p(Engines.config(:root))
|
33
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2004 David Heinemeier Hansson
|
3
|
+
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# Engine Hacks by James Adam, 2005.
|
24
|
+
#++
|
25
|
+
|
26
|
+
# Overriding ActionMailer to teach it about Engines...
|
27
|
+
module ActionMailer
|
28
|
+
class Base
|
29
|
+
|
30
|
+
# Initialize the mailer via the given +method_name+. The body will be
|
31
|
+
# rendered and a new TMail::Mail object created.
|
32
|
+
def create!(method_name, *parameters) #:nodoc:
|
33
|
+
initialize_defaults(method_name)
|
34
|
+
send(method_name, *parameters)
|
35
|
+
|
36
|
+
|
37
|
+
# If an explicit, textual body has not been set, we check assumptions.
|
38
|
+
unless String === @body
|
39
|
+
# First, we look to see if there are any likely templates that match,
|
40
|
+
# which include the content-type in their file name (i.e.,
|
41
|
+
# "the_template_file.text.html.rhtml", etc.). Only do this if parts
|
42
|
+
# have not already been specified manually.
|
43
|
+
|
44
|
+
templates = get_all_templates_for_action(@template)
|
45
|
+
|
46
|
+
#RAILS_DEFAULT_LOGGER.debug "template: #{@template}; templates: #{templates.inspect}"
|
47
|
+
|
48
|
+
if @parts.empty?
|
49
|
+
|
50
|
+
# /app/views/<mailer object name> / <action>.something.rhtml
|
51
|
+
|
52
|
+
#templates = Dir.glob("#{template_path}/#{@template}.*")
|
53
|
+
|
54
|
+
# this loop expects an array of paths to actual template files which match
|
55
|
+
# the given action name
|
56
|
+
templates.each do |path|
|
57
|
+
type = (File.basename(path).split(".")[1..-2] || []).join("/")
|
58
|
+
#RAILS_DEFAULT_LOGGER.debug "type: #{type}"
|
59
|
+
next if type.empty?
|
60
|
+
#RAILS_DEFAULT_LOGGER.debug "other bit: #{File.basename(path).split(".")[0..-2].join('.')}"
|
61
|
+
@parts << Part.new(:content_type => type,
|
62
|
+
:disposition => "inline", :charset => charset,
|
63
|
+
:body => render_message(File.basename(path).split(".")[0..-2].join('.'), @body))
|
64
|
+
end
|
65
|
+
unless @parts.empty?
|
66
|
+
@content_type = "multipart/alternative"
|
67
|
+
@charset = nil
|
68
|
+
@parts = sort_parts(@parts, @implicit_parts_order)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Then, if there were such templates, we check to see if we ought to
|
73
|
+
# also render a "normal" template (without the content type). If a
|
74
|
+
# normal template exists (or if there were no implicit parts) we render
|
75
|
+
# it.
|
76
|
+
template_exists = @parts.empty?
|
77
|
+
#template_exists ||= Dir.glob("#{template_path}/#{@template}.*").any? { |i| i.split(".").length == 2 }
|
78
|
+
template_exists ||= templates.any? { |i| File.basename(i).split(".").length == 2 }
|
79
|
+
#RAILS_DEFAULT_LOGGER.debug "template_exists? #{template_exists}"
|
80
|
+
@body = render_message(@template, @body) if template_exists
|
81
|
+
|
82
|
+
# Finally, if there are other message parts and a textual body exists,
|
83
|
+
# we shift it onto the front of the parts and set the body to nil (so
|
84
|
+
# that create_mail doesn't try to render it in addition to the parts).
|
85
|
+
if !@parts.empty? && String === @body
|
86
|
+
@parts.unshift Part.new(:charset => charset, :body => @body)
|
87
|
+
@body = nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# If this is a multipart e-mail add the mime_version if it is not
|
92
|
+
# already set.
|
93
|
+
@mime_version ||= "1.0" if !@parts.empty?
|
94
|
+
|
95
|
+
# build the mail object itself
|
96
|
+
@mail = create_mail
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
|
102
|
+
# JGA - Modified to pass the method name to initialize_template_class
|
103
|
+
def render(opts)
|
104
|
+
body = opts.delete(:body)
|
105
|
+
initialize_template_class(body, opts[:file]).render(opts)
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
# Return all ActionView template paths from the app and all Engines
|
110
|
+
def template_paths
|
111
|
+
paths = [template_path]
|
112
|
+
Engines::ActiveEngines.each { |engine|
|
113
|
+
# add a path for every engine if one exists.
|
114
|
+
engine_template_path = File.join(engine.root, "app", "views", mailer_name)
|
115
|
+
paths << engine_template_path if File.exists?(engine_template_path)
|
116
|
+
}
|
117
|
+
paths
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns a list of all template paths in the app and Engines
|
121
|
+
# which contain templates that might be used for the given action
|
122
|
+
def get_all_templates_for_action(action)
|
123
|
+
# can we trust uniq! to do this? i'm not sure...
|
124
|
+
templates = []
|
125
|
+
seen_names = []
|
126
|
+
template_paths.each { |path|
|
127
|
+
all_templates_for_path = Dir.glob(File.join(path, "#{action}.*"))
|
128
|
+
all_templates_for_path.each { |template|
|
129
|
+
name = File.basename(template)
|
130
|
+
if !seen_names.include?(name)
|
131
|
+
seen_names << name
|
132
|
+
templates << template
|
133
|
+
end
|
134
|
+
}
|
135
|
+
}
|
136
|
+
templates
|
137
|
+
end
|
138
|
+
|
139
|
+
# Returns the first path to the given template in our
|
140
|
+
# app/Engine 'chain'.
|
141
|
+
def find_template_root_for(template)
|
142
|
+
all_paths = get_all_templates_for_action(template)
|
143
|
+
if all_paths.empty?
|
144
|
+
return template_path
|
145
|
+
else
|
146
|
+
return File.dirname(all_paths[0])
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# JGA - changed here to include the method name that we
|
151
|
+
# are interested in, so that we can re-locate the proper
|
152
|
+
# template root
|
153
|
+
def initialize_template_class(assigns, method_name)
|
154
|
+
engine_template = find_template_root_for(method_name)
|
155
|
+
ActionView::Base.new(engine_template, assigns, self)
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2004 David Heinemeier Hansson
|
3
|
+
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# Engine Hacks by James Adam, 2005.
|
24
|
+
#++
|
25
|
+
|
26
|
+
require 'fileutils'
|
27
|
+
|
28
|
+
module ::ActionView
|
29
|
+
class Base
|
30
|
+
private
|
31
|
+
def full_template_path(template_path, extension)
|
32
|
+
|
33
|
+
# If the template exists in the normal application directory,
|
34
|
+
# return that path
|
35
|
+
default_template = "#{@base_path}/#{template_path}.#{extension}"
|
36
|
+
return default_template if File.exist?(default_template)
|
37
|
+
|
38
|
+
# Otherwise, check in the engines to see if the template can be found there.
|
39
|
+
# Load this in order so that more recently started Engines will take priority.
|
40
|
+
Engines::ActiveEngines.each do |engine|
|
41
|
+
site_specific_path = File.join(engine.root, 'app', 'views', template_path.to_s + '.' + extension.to_s)
|
42
|
+
return site_specific_path if File.exist?(site_specific_path)
|
43
|
+
end
|
44
|
+
|
45
|
+
# If it cannot be found anywhere, return the default path, where the
|
46
|
+
# user *should* have put it.
|
47
|
+
return "#{@base_path}/#{template_path}.#{extension}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
# add methods to handle including javascripts and stylesheets
|
53
|
+
module Helpers
|
54
|
+
module AssetTagHelper
|
55
|
+
# Returns a stylesheet link tag to the named stylesheet(s) for the given
|
56
|
+
# engine. A stylesheet with the same name as the engine is included automatically.
|
57
|
+
# If other names are supplied, those stylesheets from within the same engine
|
58
|
+
# will be linked too.
|
59
|
+
#
|
60
|
+
# engine_stylesheet "my_engine" =>
|
61
|
+
# <link href="/engine_files/my_engine/stylesheets/my_engine.css" media="screen" rel="Stylesheet" type="text/css" />
|
62
|
+
#
|
63
|
+
# engine_stylesheet "my_engine", "another_file", "one_more" =>
|
64
|
+
# <link href="/engine_files/my_engine/stylesheets/my_engine.css" media="screen" rel="Stylesheet" type="text/css" />
|
65
|
+
# <link href="/engine_files/my_engine/stylesheets/another_file.css" media="screen" rel="Stylesheet" type="text/css" />
|
66
|
+
# <link href="/engine_files/my_engine/stylesheets/one_more.css" media="screen" rel="Stylesheet" type="text/css" />
|
67
|
+
#
|
68
|
+
# Any options supplied as a Hash as the last argument will be processed as in
|
69
|
+
# stylesheet_link_tag.
|
70
|
+
#
|
71
|
+
def engine_stylesheet(engine_name, *sources)
|
72
|
+
stylesheet_link_tag(*convert_public_sources(engine_name, :stylesheet, sources))
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns a javascript link tag to the named stylesheet(s) for the given
|
76
|
+
# engine. A javascript file with the same name as the engine is included automatically.
|
77
|
+
# If other names are supplied, those javascript from within the same engine
|
78
|
+
# will be linked too.
|
79
|
+
#
|
80
|
+
# engine_javascript "my_engine" =>
|
81
|
+
# <script type="text/javascript" src="/engine_files/my_engine/javascripts/my_engine.js"></script>
|
82
|
+
#
|
83
|
+
# engine_javascript "my_engine", "another_file", "one_more" =>
|
84
|
+
# <script type="text/javascript" src="/engine_files/my_engine/javascripts/my_engine.js"></script>
|
85
|
+
# <script type="text/javascript" src="/engine_files/my_engine/javascripts/another_file.js"></script>
|
86
|
+
# <script type="text/javascript" src="/engine_files/my_engine/javascripts/one_more.js"></script>
|
87
|
+
#
|
88
|
+
# Any options supplied as a Hash as the last argument will be processed as in
|
89
|
+
# javascript_include_tag.
|
90
|
+
#
|
91
|
+
def engine_javascript(engine_name, *sources)
|
92
|
+
javascript_include_tag(*convert_public_sources(engine_name, :javascript, sources))
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
# convert the engine public file sources into actual public paths
|
97
|
+
# type:
|
98
|
+
# :stylesheet
|
99
|
+
# :javascript
|
100
|
+
# if engine_name does not end in engine, "_engine" is appended automatically.
|
101
|
+
def convert_public_sources(engine_name, type, sources)
|
102
|
+
options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { }
|
103
|
+
new_sources = []
|
104
|
+
|
105
|
+
full_engine_name = engine_name
|
106
|
+
full_engine_name += "_engine" if !(engine_name =~ /\_engine$/)
|
107
|
+
|
108
|
+
case type
|
109
|
+
when :javascript
|
110
|
+
type_dir = "javascripts"
|
111
|
+
ext = "js"
|
112
|
+
when :stylesheet
|
113
|
+
type_dir = "stylesheets"
|
114
|
+
ext = "css"
|
115
|
+
end
|
116
|
+
|
117
|
+
default = "/#{Engines.config(:public_dir)}/#{full_engine_name}/#{type_dir}/#{engine_name}"
|
118
|
+
if defined?(RAILS_ROOT) && File.exists?(File.join(RAILS_ROOT, "public", "#{default}.#{ext}"))
|
119
|
+
new_sources << default
|
120
|
+
end
|
121
|
+
|
122
|
+
sources.each { |name|
|
123
|
+
new_sources << "/#{Engines.config(:public_dir)}/#{full_engine_name}/#{type_dir}/#{name}"
|
124
|
+
}
|
125
|
+
|
126
|
+
new_sources << options
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2004 David Heinemeier Hansson
|
3
|
+
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# Engine Hacks by James Adam, 2005.
|
24
|
+
#++
|
25
|
+
|
26
|
+
module ::Dependencies
|
27
|
+
def require_or_load(file_name)
|
28
|
+
# try and load the framework code first
|
29
|
+
# can't use model, as there's nothing in the name to indicate that the file is a 'model' file
|
30
|
+
# rather than a library or anything else.
|
31
|
+
['controller', 'helper'].each do |type|
|
32
|
+
if file_name.include?('_' + type)
|
33
|
+
Engines::ActiveEngines.reverse.each do |engine|
|
34
|
+
engine_file_name = File.join(engine.root, 'app', "#{type}s", File.basename(file_name))
|
35
|
+
engine_file_name += '.rb' unless engine_file_name[-3..-1] == '.rb'
|
36
|
+
if File.exist? engine_file_name
|
37
|
+
load? ? load(engine_file_name) : require(engine_file_name)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# finally, load any application-specific controller classes.
|
44
|
+
file_name = "#{file_name}.rb" unless ! load? || file_name [-3..-1] == '.rb'
|
45
|
+
load? ? load(file_name) : require(file_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
class RootLoadingModule < LoadingModule
|
49
|
+
# hack to allow adding to the load paths within the Rails Dependencies mechanism.
|
50
|
+
# this allows Engine classes to be unloaded and loaded along with standard
|
51
|
+
# Rails application classes.
|
52
|
+
def add_path(path)
|
53
|
+
@load_paths << (path.kind_of?(ConstantLoadPath) ? path : ConstantLoadPath.new(path))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,292 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005 James Adam
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require 'ruby_extensions'
|
25
|
+
require 'dependencies_extensions'
|
26
|
+
require 'action_view_extensions'
|
27
|
+
require 'action_mailer_extensions'
|
28
|
+
require 'testing_extensions'
|
29
|
+
|
30
|
+
|
31
|
+
# Holds the Rails Engine loading logic and default constants
|
32
|
+
module ::Engines
|
33
|
+
|
34
|
+
# An array of active engines (actually paths to active engines)
|
35
|
+
ActiveEngines = []
|
36
|
+
|
37
|
+
# The root directory for engines
|
38
|
+
config :root, File.join(RAILS_ROOT, "vendor", "plugins")
|
39
|
+
|
40
|
+
# The name of the public folder under which engine files are copied
|
41
|
+
config :public_dir, "engine_files"
|
42
|
+
|
43
|
+
class << self
|
44
|
+
|
45
|
+
# Initializes a Rails Engine by loading the engine's init.rb file and
|
46
|
+
# ensuring that any engine controllers are added to the load path.
|
47
|
+
# This will also copy any files in a directory named 'public'
|
48
|
+
# into the public webserver directory. Example usage:
|
49
|
+
#
|
50
|
+
# Engines.start :login
|
51
|
+
# Engines.start :login_engine # equivalent
|
52
|
+
#
|
53
|
+
# A list of engine names can be specified:
|
54
|
+
#
|
55
|
+
# Engines.start :login, :user, :wiki
|
56
|
+
#
|
57
|
+
# The engines will be loaded in the order given.
|
58
|
+
# If no engine names are given, all engines will be started.
|
59
|
+
#
|
60
|
+
# Options can include:
|
61
|
+
# * :copy_files => true | false
|
62
|
+
# * :engine_name => the name within the plugins directory this engine resides, if
|
63
|
+
# different from the first parameter
|
64
|
+
#
|
65
|
+
# Note that if a list of engines is given, the options will apply to ALL engines.
|
66
|
+
def start(*args)
|
67
|
+
|
68
|
+
options = (args.last.is_a? Hash) ? args.pop : {}
|
69
|
+
|
70
|
+
if args.empty?
|
71
|
+
start_all
|
72
|
+
return
|
73
|
+
else
|
74
|
+
args.each do |engine_name|
|
75
|
+
start_engine(engine_name, options)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Starts all available engines. Plugins are considered engines if they
|
81
|
+
# include an init_engine.rb file, or they are named <something>_engine.
|
82
|
+
def start_all()
|
83
|
+
plugins = Dir[File.join(config(:root), "*")]
|
84
|
+
RAILS_DEFAULT_LOGGER.debug "considering plugins: #{plugins.inspect}"
|
85
|
+
plugins.each { |plugin|
|
86
|
+
engine_name = File.basename(plugin)
|
87
|
+
if File.exist?(File.join(plugin, "init_engine.rb")) or
|
88
|
+
(engine_name =~ /_engine$/)
|
89
|
+
# start the engine...
|
90
|
+
start(engine_name)
|
91
|
+
end
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
def start_engine(engine_name, options={})
|
96
|
+
|
97
|
+
current_engine = Engine.new
|
98
|
+
current_engine.name = options[:engine_name] || engine_name
|
99
|
+
current_engine.root = get_engine_dir(engine_name)
|
100
|
+
|
101
|
+
#engine_name = options[:engine_name] || engine
|
102
|
+
#engine_dir = get_engine_dir(engine_name)
|
103
|
+
|
104
|
+
RAILS_DEFAULT_LOGGER.debug "Trying to start engine '#{current_engine.name}' from '#{File.expand_path(current_engine.root)}'"
|
105
|
+
|
106
|
+
# put this engine at the front of the ActiveEngines list
|
107
|
+
Engines::ActiveEngines.unshift current_engine #engine_dir
|
108
|
+
|
109
|
+
# add the code directories of this engine to the load path
|
110
|
+
add_engine_to_load_path(current_engine) #engine_dir)
|
111
|
+
|
112
|
+
# load the engine's init.rb file
|
113
|
+
startup_file = File.join(current_engine.root, "init_engine.rb")
|
114
|
+
if File.exist?(startup_file)
|
115
|
+
eval(IO.read(startup_file), binding, startup_file)
|
116
|
+
#require startup_file
|
117
|
+
else
|
118
|
+
RAILS_DEFAULT_LOGGER.warn "WARNING: No init_engines.rb file found for engine '#{current_engine.name}'..."
|
119
|
+
end
|
120
|
+
|
121
|
+
# add the controller path to the Dependency system
|
122
|
+
Controllers.add_path(File.join(current_engine.root, 'app', 'controllers'))
|
123
|
+
|
124
|
+
# copy the files unless indicated otherwise
|
125
|
+
if options[:copy_files] != false
|
126
|
+
copy_engine_files(current_engine)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Adds all directories in the /app and /lib directories within the engine
|
131
|
+
# to the load path
|
132
|
+
def add_engine_to_load_path(engine)
|
133
|
+
# Add ALL paths under the engine root to the load path
|
134
|
+
app_dirs = [engine.root + "/app/controllers", engine.root + "/app/models",
|
135
|
+
engine.root + "/app/helpers"]
|
136
|
+
lib_dirs = Dir[engine.root + "/lib/**/*"] + [engine.root, "lib"]
|
137
|
+
load_paths = (app_dirs + lib_dirs).select { |d|
|
138
|
+
File.directory?(d)
|
139
|
+
}
|
140
|
+
|
141
|
+
# Remove other engines from the $LOAD_PATH bby matching against the engine.root values
|
142
|
+
# in ActiveEngines. Store the removed engines in the order they came off.
|
143
|
+
#
|
144
|
+
# This is a hack - if Ticket http://dev.rubyonrails.com/ticket/2817 is accepted, then
|
145
|
+
# a new Engines system can be developed which only modifies load paths in one sweep,
|
146
|
+
# thus avoiding this.
|
147
|
+
#
|
148
|
+
|
149
|
+
old_plugin_paths = []
|
150
|
+
# assumes that all engines are at the bottom of the $LOAD_PATH
|
151
|
+
while (File.expand_path($LOAD_PATH.last).index(File.expand_path(Engines.config(:root))) == 0) do
|
152
|
+
old_plugin_paths.unshift($LOAD_PATH.pop)
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
# add these LAST on the load path.
|
157
|
+
load_paths.reverse.each { |dir|
|
158
|
+
if File.directory?(dir)
|
159
|
+
RAILS_DEFAULT_LOGGER.debug "adding #{File.expand_path(dir)} to the load path"
|
160
|
+
$LOAD_PATH.push(File.expand_path(dir))
|
161
|
+
end
|
162
|
+
}
|
163
|
+
|
164
|
+
# Add the other engines back onto the bottom of the $LOAD_PATH. Put them back on in
|
165
|
+
# the same order.
|
166
|
+
$LOAD_PATH.push(*old_plugin_paths)
|
167
|
+
$LOAD_PATH.uniq!
|
168
|
+
end
|
169
|
+
|
170
|
+
# Replicates the subdirectories under the engine's /public directory into
|
171
|
+
# the corresponding public directory.
|
172
|
+
def copy_engine_files(engine)
|
173
|
+
|
174
|
+
#engine_dir = get_engine_dir(engine)
|
175
|
+
|
176
|
+
# create the /public/frameworks directory if it doesn't exist
|
177
|
+
public_engine_dir = File.expand_path(File.join(RAILS_ROOT, "public", Engines.config(:public_dir)))
|
178
|
+
|
179
|
+
if !File.exists?(public_engine_dir)
|
180
|
+
# create the public/engines directory, with a warning message in it.
|
181
|
+
RAILS_DEFAULT_LOGGER.debug "Creating public engine files directory '#{public_engine_dir}'"
|
182
|
+
FileUtils.mkdir(public_engine_dir)
|
183
|
+
File.open(File.join(public_engine_dir, "README"), "w") do |f|
|
184
|
+
f.puts <<EOS
|
185
|
+
Files in this directory are automatically generated from your Rails Engines.
|
186
|
+
They are copied from the 'public' directories of each engine into this directory
|
187
|
+
each time Rails starts (server, console... any time 'start_engine' is called).
|
188
|
+
Any edits you make will NOT persist across the next server restart; instead you
|
189
|
+
should edit the files within the <engine_name>/public directory itself.
|
190
|
+
EOS
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
source = File.join(engine.root, "public") #engine_dir, "public")
|
195
|
+
RAILS_DEFAULT_LOGGER.debug "Attempting to copy public engine files from '#{source}'"
|
196
|
+
|
197
|
+
# if there is no public directory, just return after this file
|
198
|
+
return if !File.exist?(source)
|
199
|
+
|
200
|
+
source_files = Dir[source + "/**/*"]
|
201
|
+
source_dirs = source_files.select { |d| File.directory?(d) }
|
202
|
+
source_files -= source_dirs
|
203
|
+
|
204
|
+
RAILS_DEFAULT_LOGGER.debug "source dirs: #{source_dirs.inspect}"
|
205
|
+
|
206
|
+
# ensure that we are copying to <something>_engine, whatever the user gives us
|
207
|
+
full_engine_name = engine.name
|
208
|
+
full_engine_name += "_engine" if !(full_engine_name =~ /\_engine$/)
|
209
|
+
|
210
|
+
|
211
|
+
# create all the directories, transforming the old path into the new path
|
212
|
+
source_dirs.uniq.each { |dir|
|
213
|
+
begin
|
214
|
+
|
215
|
+
# strip out the base path and add the result to the public path
|
216
|
+
relative_dir = dir.gsub(File.join(engine.root, "public"), full_engine_name)
|
217
|
+
target_dir = File.join(public_engine_dir, relative_dir)
|
218
|
+
unless File.exist?(target_dir)
|
219
|
+
RAILS_DEFAULT_LOGGER.debug "creating directory '#{target_dir}'"
|
220
|
+
FileUtils.mkdir_p(File.join(public_engine_dir, relative_dir))
|
221
|
+
end
|
222
|
+
rescue Exception => e
|
223
|
+
raise "Could not create directory #{target_dir}: \n" + e
|
224
|
+
end
|
225
|
+
}
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
# copy all the files, transforming the old path into the new path
|
230
|
+
source_files.uniq.each { |file|
|
231
|
+
begin
|
232
|
+
# change the path from the ENGINE ROOT to the public directory root for this engine
|
233
|
+
target = file.gsub(File.join(engine.root, "public"),
|
234
|
+
File.join(public_engine_dir, full_engine_name))
|
235
|
+
unless File.exist?(target) && FileUtils.identical?(file, target)
|
236
|
+
RAILS_DEFAULT_LOGGER.debug "copying file '#{file}' to '#{target}'"
|
237
|
+
FileUtils.cp(file, target)
|
238
|
+
end
|
239
|
+
rescue Exception => e
|
240
|
+
raise "Could not copy #{file} to #{target}: \n" + e
|
241
|
+
end
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
#private
|
247
|
+
# Return the directory in which this engine is present
|
248
|
+
def get_engine_dir(engine_name)
|
249
|
+
engine_dir=File.join(Engines.config(:root), engine_name.to_s)
|
250
|
+
|
251
|
+
if !File.exist?(engine_dir)
|
252
|
+
# try adding "_engine" to the end of the path.
|
253
|
+
engine_dir += "_engine"
|
254
|
+
if !File.exist?(engine_dir)
|
255
|
+
raise "Cannot find the engine '#{engine_name}' in either /vendor/plugins/#{engine} or /vendor/plugins/#{engine}_engine..."
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
engine_dir
|
260
|
+
end
|
261
|
+
|
262
|
+
# Returns the Engine object for the specified engine, e.g.:
|
263
|
+
# Engines.get(:login)
|
264
|
+
def get(name)
|
265
|
+
ActiveEngines.find { |e| e.name == name.to_s || e.name == "#{name}_engine" }
|
266
|
+
end
|
267
|
+
|
268
|
+
# Returns the Engine object for the current engine, i.e. the engine
|
269
|
+
# in which the currently executing code lies.
|
270
|
+
def current()
|
271
|
+
#puts caller.inspect
|
272
|
+
#puts ">>> " + caller[0]
|
273
|
+
current_file = caller[0]
|
274
|
+
ActiveEngines.find do |engine|
|
275
|
+
File.expand_path(current_file).index(File.expand_path(engine.root)) == 0
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# A simple class for holding information about loaded engines
|
282
|
+
class Engine
|
283
|
+
|
284
|
+
# Returns the base path of this engine
|
285
|
+
attr_accessor :root
|
286
|
+
|
287
|
+
# Returns the name of this engine
|
288
|
+
attr_reader :name
|
289
|
+
|
290
|
+
def name=(val) @name = val.to_s end
|
291
|
+
def to_s() "Engine<#{@name}>" end
|
292
|
+
end
|