parlement 0.1

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 (162) hide show
  1. data/CHANGES +709 -0
  2. data/COPYING +223 -0
  3. data/README +20 -0
  4. data/Rakefile +136 -0
  5. data/app/controllers/account_controller.rb +181 -0
  6. data/app/controllers/application.rb +30 -0
  7. data/app/controllers/elt_controller.rb +83 -0
  8. data/app/helpers/account_helper.rb +2 -0
  9. data/app/helpers/application_helper.rb +4 -0
  10. data/app/helpers/elt_helper.rb +37 -0
  11. data/app/helpers/live_tree.rb +238 -0
  12. data/app/helpers/mailman.rb +96 -0
  13. data/app/models/attachment.rb +4 -0
  14. data/app/models/elt.rb +17 -0
  15. data/app/models/mail.rb +4 -0
  16. data/app/models/notifier.rb +13 -0
  17. data/app/models/person.rb +9 -0
  18. data/app/models/user.rb +7 -0
  19. data/app/models/user_notify.rb +75 -0
  20. data/app/views/account/_help.rhtml +23 -0
  21. data/app/views/account/_login.rhtml +57 -0
  22. data/app/views/account/_show.rhtml +31 -0
  23. data/app/views/account/logout.rhtml +10 -0
  24. data/app/views/account/signup.rhtml +17 -0
  25. data/app/views/account/welcome.rhtml +13 -0
  26. data/app/views/elt/_elt.rhtml +105 -0
  27. data/app/views/elt/_form.rhtml +31 -0
  28. data/app/views/elt/_list.rhtml +28 -0
  29. data/app/views/elt/new.rhtml +102 -0
  30. data/app/views/elt/rss.rxml +31 -0
  31. data/app/views/elt/show.rhtml +46 -0
  32. data/app/views/elt/show_tree.rhtml +8 -0
  33. data/app/views/layouts/scaffold.rhtml +13 -0
  34. data/app/views/layouts/top.rhtml +45 -0
  35. data/app/views/notifier/changeEmail.rhtml +10 -0
  36. data/config/boot.rb +17 -0
  37. data/config/database.yml +82 -0
  38. data/config/environment.rb +92 -0
  39. data/config/environments/development.rb +17 -0
  40. data/config/environments/production.rb +17 -0
  41. data/config/environments/test.rb +17 -0
  42. data/config/environments/user_environment.rb +1 -0
  43. data/config/routes.rb +28 -0
  44. data/db/ROOT/CV.txt +166 -0
  45. data/db/ROOT/IP.txt +3 -0
  46. data/db/ROOT/parleR.txt +3 -0
  47. data/db/ROOT/parlement/security.txt +34 -0
  48. data/db/ROOT/parlement/test.txt +4 -0
  49. data/db/ROOT/parlement.txt +51 -0
  50. data/db/ROOT/perso.txt +215 -0
  51. data/db/schema.sql +127 -0
  52. data/lib/data_import.rb +54 -0
  53. data/lib/file_column.rb +263 -0
  54. data/lib/file_column_helper.rb +45 -0
  55. data/lib/localization.rb +88 -0
  56. data/lib/localizer.rb +88 -0
  57. data/lib/login_system.rb +87 -0
  58. data/lib/rails_file_column.rb +19 -0
  59. data/lib/user_system.rb +101 -0
  60. data/public/404.html +8 -0
  61. data/public/500.html +8 -0
  62. data/public/dispatch.cgi +10 -0
  63. data/public/dispatch.fcgi +24 -0
  64. data/public/dispatch.rb +10 -0
  65. data/public/engine_files/README +5 -0
  66. data/public/engine_files/login_engine/stylesheets/login_engine.css +81 -0
  67. data/public/favicon.ico +0 -0
  68. data/public/favicon.png +0 -0
  69. data/public/images/live_tree_branch_collapsed_icon.gif +0 -0
  70. data/public/images/live_tree_branch_expanded_icon.gif +0 -0
  71. data/public/images/live_tree_leaf_icon.gif +0 -0
  72. data/public/images/live_tree_loading_spinner.gif +0 -0
  73. data/public/images/webfeed.gif +0 -0
  74. data/public/javascripts/controls.js +721 -0
  75. data/public/javascripts/dragdrop.js +519 -0
  76. data/public/javascripts/effects.js +992 -0
  77. data/public/javascripts/live_tree.js +749 -0
  78. data/public/javascripts/prototype.js +1726 -0
  79. data/public/javascripts/scriptaculous.js +47 -0
  80. data/public/javascripts/slider.js +258 -0
  81. data/public/oldREADME +190 -0
  82. data/public/oldindex.html +78 -0
  83. data/public/robots.txt +1 -0
  84. data/public/stylesheets/default.css +238 -0
  85. data/public/stylesheets/live_tree.css +62 -0
  86. data/public/stylesheets/scaffold.css +74 -0
  87. data/script/about +3 -0
  88. data/script/benchmarker +19 -0
  89. data/script/breakpointer +3 -0
  90. data/script/console +3 -0
  91. data/script/create_db +7 -0
  92. data/script/destroy +3 -0
  93. data/script/generate +3 -0
  94. data/script/performance/benchmarker +3 -0
  95. data/script/performance/profiler +3 -0
  96. data/script/plugin +3 -0
  97. data/script/process/reaper +3 -0
  98. data/script/process/spawner +3 -0
  99. data/script/process/spinner +3 -0
  100. data/script/profiler +34 -0
  101. data/script/runner +3 -0
  102. data/script/server +3 -0
  103. data/test/fixtures/attachments.yml +10 -0
  104. data/test/fixtures/elts.yml +15 -0
  105. data/test/fixtures/mails.yml +7 -0
  106. data/test/fixtures/people.yml +49 -0
  107. data/test/fixtures/users.yml +41 -0
  108. data/test/functional/account_controller_test.rb +239 -0
  109. data/test/functional/elt_controller_test.rb +18 -0
  110. data/test/mocks/test/time.rb +17 -0
  111. data/test/mocks/test/user_notify.rb +16 -0
  112. data/test/test_helper.rb +28 -0
  113. data/test/unit/attachment_test.rb +14 -0
  114. data/test/unit/elt_test.rb +14 -0
  115. data/test/unit/mail_test.rb +14 -0
  116. data/test/unit/notifier_test.rb +31 -0
  117. data/test/unit/person_test.rb +24 -0
  118. data/test/unit/user_test.rb +94 -0
  119. data/vendor/plugins/engines/CHANGELOG +7 -0
  120. data/vendor/plugins/engines/README +128 -0
  121. data/vendor/plugins/engines/init.rb +33 -0
  122. data/vendor/plugins/engines/lib/action_mailer_extensions.rb +160 -0
  123. data/vendor/plugins/engines/lib/action_view_extensions.rb +130 -0
  124. data/vendor/plugins/engines/lib/dependencies_extensions.rb +56 -0
  125. data/vendor/plugins/engines/lib/engines.rb +292 -0
  126. data/vendor/plugins/engines/lib/ruby_extensions.rb +127 -0
  127. data/vendor/plugins/engines/lib/testing_extensions.rb +33 -0
  128. data/vendor/plugins/engines/test/ruby_extensions_test.rb +94 -0
  129. data/vendor/plugins/login_engine/README +258 -0
  130. data/vendor/plugins/login_engine/app/controllers/user_controller.rb +248 -0
  131. data/vendor/plugins/login_engine/app/helpers/user_helper.rb +88 -0
  132. data/vendor/plugins/login_engine/app/models/user.rb +7 -0
  133. data/vendor/plugins/login_engine/app/models/user_notify.rb +75 -0
  134. data/vendor/plugins/login_engine/app/views/user/_edit.rhtml +11 -0
  135. data/vendor/plugins/login_engine/app/views/user/_password.rhtml +9 -0
  136. data/vendor/plugins/login_engine/app/views/user/change_password.rhtml +17 -0
  137. data/vendor/plugins/login_engine/app/views/user/edit.rhtml +23 -0
  138. data/vendor/plugins/login_engine/app/views/user/forgot_password.rhtml +18 -0
  139. data/vendor/plugins/login_engine/app/views/user/home.rhtml +7 -0
  140. data/vendor/plugins/login_engine/app/views/user/login.rhtml +17 -0
  141. data/vendor/plugins/login_engine/app/views/user/logout.rhtml +8 -0
  142. data/vendor/plugins/login_engine/app/views/user/signup.rhtml +17 -0
  143. data/vendor/plugins/login_engine/app/views/user_notify/change_password.rhtml +10 -0
  144. data/vendor/plugins/login_engine/app/views/user_notify/delete.rhtml +5 -0
  145. data/vendor/plugins/login_engine/app/views/user_notify/forgot_password.rhtml +11 -0
  146. data/vendor/plugins/login_engine/app/views/user_notify/pending_delete.rhtml +9 -0
  147. data/vendor/plugins/login_engine/app/views/user_notify/signup.rhtml +12 -0
  148. data/vendor/plugins/login_engine/db/schema.rb +25 -0
  149. data/vendor/plugins/login_engine/init_engine.rb +10 -0
  150. data/vendor/plugins/login_engine/lib/login_engine/authenticated_system.rb +107 -0
  151. data/vendor/plugins/login_engine/lib/login_engine/authenticated_user.rb +149 -0
  152. data/vendor/plugins/login_engine/lib/login_engine.rb +58 -0
  153. data/vendor/plugins/login_engine/public/stylesheets/login_engine.css +81 -0
  154. data/vendor/plugins/login_engine/tasks/tasks.rake +4 -0
  155. data/vendor/plugins/login_engine/test/fixtures/templates/users.yml +41 -0
  156. data/vendor/plugins/login_engine/test/fixtures/users.yml +41 -0
  157. data/vendor/plugins/login_engine/test/functional/user_controller_test.rb +533 -0
  158. data/vendor/plugins/login_engine/test/mocks/mail.rb +14 -0
  159. data/vendor/plugins/login_engine/test/mocks/time.rb +19 -0
  160. data/vendor/plugins/login_engine/test/test_helper.rb +15 -0
  161. data/vendor/plugins/login_engine/test/unit/user_test.rb +94 -0
  162. 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