parlement 0.1

Sign up to get free protection for your applications and to get access to all the features.
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