ixtlan-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. data/README.textile +31 -0
  2. data/features/generators.feature +5 -0
  3. data/features/step_definitions/simple_steps.rb +22 -0
  4. data/lib/generators/ixtlan/base.rb +45 -0
  5. data/lib/generators/ixtlan/configuration_model/configuration_model_generator.rb +12 -0
  6. data/lib/generators/ixtlan/configuration_scaffold/configuration_scaffold_generator.rb +12 -0
  7. data/lib/generators/ixtlan/setup/setup_generator.rb +38 -0
  8. data/lib/generators/ixtlan/setup/templates/application_layout.html.erb +17 -0
  9. data/lib/generators/ixtlan/setup/templates/database.yml.example +48 -0
  10. data/lib/generators/ixtlan/setup/templates/error.html.erb +1 -0
  11. data/lib/generators/ixtlan/setup/templates/error_with_session.html.erb +1 -0
  12. data/lib/generators/ixtlan/setup/templates/gitignore +2 -0
  13. data/lib/generators/ixtlan/setup/templates/initializer.rb +63 -0
  14. data/lib/generators/ixtlan/setup/templates/preinitializer.rb +31 -0
  15. data/lib/generators/ixtlan/setup/templates/production.yml.example +8 -0
  16. data/lib/generators/ixtlan/setup/templates/stale.html.erb +2 -0
  17. data/lib/generators/model/model_generator.rb +12 -0
  18. data/lib/generators/rails/templates/_form.html.erb +25 -0
  19. data/lib/generators/rails/templates/edit.html.erb +24 -0
  20. data/lib/generators/rails/templates/index.html.erb +47 -0
  21. data/lib/generators/rails/templates/migration.rb +19 -0
  22. data/lib/generators/rails/templates/model.rb +16 -0
  23. data/lib/generators/rails/templates/new.html.erb +11 -0
  24. data/lib/generators/rails/templates/show.html.erb +30 -0
  25. data/lib/generators/scaffold/scaffold_generator.rb +31 -0
  26. data/lib/generators/scaffold_controller/scaffold_controller_generator.rb +48 -0
  27. data/lib/generators/scaffold_controller/templates/controller.rb +99 -0
  28. data/lib/generators/scaffold_controller/templates/singleton_controller.rb +43 -0
  29. data/lib/ixtlan/core/cache_headers.rb +86 -0
  30. data/lib/ixtlan/core/configuration_manager.rb +43 -0
  31. data/lib/ixtlan/core/configuration_rack.rb +19 -0
  32. data/lib/ixtlan/core/controllers/configuration_controller.rb +48 -0
  33. data/lib/ixtlan/core/railtie.rb +47 -0
  34. data/lib/ixtlan-core.rb +3 -0
  35. metadata +152 -0
data/README.textile ADDED
@@ -0,0 +1,31 @@
1
+ h1. Ixtlan
2
+
3
+ p. this project is just a compilation of things I am doing all over the place in my projects. there is a focus on privacy protection which needs a strong security in the first place.
4
+
5
+ p. this gem is quite invasive in terms of default templates of rails3. first it adds json serializers and looks for a lot of switches from other gems like 'ixtlan-audit', 'ixtlan-session-timeout', 'ixtlan-error-handler', 'rails-resty-generators', etc
6
+
7
+ h2. setup generator
8
+
9
+ p. this just adds an preinitializer to the rails application which allows to keep the config/database.yml almost as is and allows to put the passwords for the production database into a 'production.yml' - just ignore that production.yml from git and keep it only on the deployed server. same you can do for an external mail provider.
10
+
11
+ p. further if you can configure a configuration (singleton) model which allows to register components which can notified when a configuration changes.
12
+
13
+ p. since the model generator also needs to work nice with rails-resty-generators it add beside the "reference/belongs_to" also a "has_one" and "has_many" types. this allows to generate the ruby models along with java GWT models in a similar manner (note: restrictions and short comings are there . . .).
14
+
15
+ h2. cache headers
16
+
17
+ p. that is the only "real" feature of the ixtlan-core gem. with this you can control the cache header with three predefined modi:
18
+
19
+ * private: no caching of data for any proxy or browser
20
+
21
+ * protected: only browser can cache
22
+
23
+ * public: proxies and browsers can cache as desired
24
+
25
+ of any sensitive data go for the private mode.
26
+
27
+ p. this control is only active when there is logged in user, i.e. controller.current_user != null. also when the controller does not set the cache-header the rails default is used.
28
+
29
+ h3. credits
30
+
31
+ p. the cache header uses http://code.google.com/p/doctype/wiki/ArticleHttpCaching as specification
@@ -0,0 +1,5 @@
1
+ Feature: Generators for Ixtlan Audit
2
+
3
+ Scenario: The slf4r rails template creates a rails application which uses slf4r-wrapper
4
+ Given I create new rails application with template "simple.template"
5
+ Then the output should contain "setup slf4r logger wrapper with ActiveSupport::BufferedLogger"
@@ -0,0 +1,22 @@
1
+ require 'fileutils'
2
+ Given /^I create new rails application with template "(.*)"$/ do |template|
3
+ name = template.sub(/.template$/, '')
4
+ directory = File.join('target', name)
5
+ rails_version = ENV['RAILS_VERSION'] || '3.0.1'
6
+
7
+ ruby = defined?(JRUBY_VERSION) ? "jruby" : "ruby"
8
+ rails_command = "#{ENV['GEM_HOME']}/bin/rails"
9
+ rails_command = "-S rails" unless File.exists?(rails_command)
10
+ command = "#{rails_command} _#{rails_version}_ new #{directory} -f -m templates/#{template}"
11
+ FileUtils.rm_rf(directory)
12
+
13
+ system "#{ruby} #{command}"
14
+
15
+ @result = File.read("target/#{name}/log/development.log")
16
+ puts @result
17
+ end
18
+
19
+ Then /^the output should contain \"(.*)\"$/ do |expected|
20
+ (@result =~ /.*#{expected}.*/).should_not be_nil
21
+ end
22
+
@@ -0,0 +1,45 @@
1
+ require 'rails/generators/named_base'
2
+ module Ixtlan
3
+ module Generators
4
+ class Base < Rails::Generators::Base
5
+
6
+ argument :name, :type => :string, :required => false
7
+
8
+ protected
9
+ def generator_name
10
+ raise "please overwrite generator_name"
11
+ end
12
+
13
+ public
14
+ def create
15
+ args = []
16
+ if name
17
+ args << ARGV.shift
18
+ else
19
+ args << "configuration"
20
+ end
21
+
22
+ if defined? ::Ixtlan::Errors
23
+ args << "errors_keep_dumps:integer"
24
+ args << "errors_dir:string"
25
+ args << "errors_from:string"
26
+ args << "errors_to:string"
27
+ end
28
+
29
+ if defined? ::Ixtlan::Sessions
30
+ args << "idle_session_timeout:integer"
31
+ end
32
+
33
+ if defined? ::Ixtlan::Audit
34
+ args << "audit_keep_log:integer"
35
+ end
36
+
37
+ args += ARGV[0, 10000] || []
38
+
39
+ args << "--singleton"
40
+
41
+ generate generator_name, *args
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,12 @@
1
+ require 'generators/ixtlan/base'
2
+ module Ixtlan
3
+ module Generators
4
+ class ConfigurationModelGenerator < Base
5
+
6
+ protected
7
+ def generator_name
8
+ "model"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'generators/ixtlan/base'
2
+ module Ixtlan
3
+ module Generators
4
+ class ConfigurationScaffoldGenerator < Base
5
+
6
+ protected
7
+ def generator_name
8
+ "scaffold"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,38 @@
1
+ require 'rails/generators/base'
2
+ module Ixtlan
3
+ module Generators
4
+ class SetupGenerator < Rails::Generators::Base
5
+
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def create_preinitializer_files
9
+ template 'preinitializer.rb', File.join('config', "preinitializer.rb")
10
+ template 'gitignore', File.join('config', ".gitignore")
11
+ template 'production.yml.example', File.join('config', "production.yml.example")
12
+ template 'database.yml.example', File.join('config', "database.yml.example")
13
+ end
14
+
15
+ def create_initializer_file
16
+ template 'initializer.rb', File.join('config', "initializers", "ixtlan.rb")
17
+ end
18
+
19
+ # TODO make only if template-engine is ERB
20
+ def error_templates
21
+ if defined? Ixtlan::Errors
22
+ views_dir = File.join('app', 'views', 'errors')
23
+ ['error', 'error_with_session', 'stale'].each do |f|
24
+ file = "#{f}.html.erb"
25
+ template file, File.join(views_dir, file)
26
+ end
27
+ end
28
+ end
29
+
30
+ def create_application_layout_file
31
+ if defined? Ixtlan::Sessions
32
+ layout = File.join('app', 'views', 'layouts', 'application.html.erb')
33
+ template 'application_layout.html.erb', layout
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Schedules</title>
5
+ <%%= stylesheet_link_tag :all %>
6
+ <%%= javascript_include_tag :defaults %>
7
+ <%%= csrf_meta_tag %>
8
+ <%% if controller.respond_to?(:current_user) && controller.send(:current_user) != nil %>
9
+ <meta "http-equiv"="refresh" content="#{Configuration.instance.idle_session_timeout * 60}" />
10
+ <%% end %>
11
+ </head>
12
+ <body>
13
+
14
+ <%%= yield %>
15
+
16
+ </body>
17
+ </html>
@@ -0,0 +1,48 @@
1
+ # MySQL. Versions 4.1 and 5.0 are recommended.
2
+ #
3
+ # Install the MySQL driver:
4
+ # gem install mysql
5
+ # On Mac OS X:
6
+ # sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
7
+ # On Mac OS X Leopard:
8
+ # sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
9
+ # This sets the ARCHFLAGS environment variable to your native architecture
10
+ # On Windows:
11
+ # gem install mysql
12
+ # Choose the win32 build.
13
+ # Install MySQL and put its /bin directory on your path.
14
+ #
15
+ # And be sure to use new-style password hashing:
16
+ # http://dev.mysql.com/doc/refman/5.0/en/old-client.html
17
+ development:
18
+ adapter: mysql
19
+ encoding: utf8
20
+ reconnect: false
21
+ database: test_development
22
+ pool: 5
23
+ username: root
24
+ password:
25
+ socket: /var/run/mysqld/mysqld.sock
26
+
27
+ # Warning: The database defined as "test" will be erased and
28
+ # re-generated from your development database when you run "rake".
29
+ # Do not set this db to the same as development or production.
30
+ test:
31
+ adapter: mysql
32
+ encoding: utf8
33
+ reconnect: false
34
+ database: test_test
35
+ pool: 5
36
+ username: root
37
+ password:
38
+ socket: /var/run/mysqld/mysqld.sock
39
+
40
+ production:
41
+ adapter: mysql
42
+ encoding: utf8
43
+ reconnect: false
44
+ database: CONFIG[:db][:database]
45
+ pool: 5
46
+ username: CONFIG[:db][:username]
47
+ password: CONFIG[:db][:password]
48
+ socket: /var/run/mysqld/mysqld.sock
@@ -0,0 +1 @@
1
+ <h1><%%= @notice %></h1>
@@ -0,0 +1 @@
1
+ <h1><%%= @notice %></h1>
@@ -0,0 +1,2 @@
1
+ production.yml
2
+ *.example
@@ -0,0 +1,63 @@
1
+ # dynamic configuration through a Configuration singleton model
2
+
3
+ # configuration model
4
+ # -------------------
5
+ # CONFIGURATION = Configuration
6
+ # config.configuration_model = CONFIGURATION
7
+ <% if defined? DataMapper -%>
8
+ # config_instance = CONFIGURATION.get(1) || CONFIGURATION.new
9
+ <% else -%>
10
+ # config_instance = CONFIGURATION.find(1) || CONFIGURATION.new
11
+ <%end -%>
12
+
13
+ # notification email on errors and dump directory for the system dump
14
+ # the error dumps will be cleanup after the days to keeps dump expired
15
+ # --------------------------------------------------------------------
16
+ # config_instance.register("error_dumper") do |config|
17
+ # Rails.configuration.error_dumper.dump_dir = config.errors_dir
18
+ # Rails.configuration.error_dumper.email_from = config.errors_from
19
+ # Rails.configuration.error_dumper.email_to = config.errors_to
20
+ # Rails.configuration.error_dumper.keep_dumps = config.errors_keep_dumps # days
21
+ # end
22
+
23
+ # idle session timeout configuration (in minutes)
24
+ # -----------------------------------------------
25
+ # config_instance.register("idle_session_timeout") do |config|
26
+ # Rails.configuration.idle_session_timeout = config.idle_session_timeout
27
+ # end
28
+
29
+ # audit log manager
30
+ # -----------------
31
+
32
+ # config.audit_manager.model = MyAudit # default: Audit
33
+ # config.audit_manager.username_method = :username # default: :login
34
+
35
+ # config_instance.register("audit_manager") do |config|
36
+ # Rails.configuration.audit_manager.keep_log = config.keep_log # days
37
+ # end
38
+
39
+ # --------------------
40
+ # static configuration
41
+ # --------------------
42
+
43
+ # error dumper
44
+ # ------------
45
+ # notification email on errors and dump directory for the system dump. per
46
+ # default there is no email notification and if email_from or email_to is
47
+ # missing then there is no email too
48
+
49
+ # config.error_dumper.dump_dir = Rails.root + "/log/errors" # default: log/errors
50
+ # config.error_dumper.email_from = "no-reply@example.com"
51
+ # config.error_dumper.email_to = "developer1@example.com,developer2@example.com"
52
+ # config.error_dumper.keep_dumps = 30 # days
53
+ # config.skip_rescue_module = true # do not include the predefined Rescue
54
+
55
+ # idle session timeout configuration
56
+ # ----------------------------------
57
+ # config.idle_session_timeout = 30 #minutes
58
+
59
+ # audit log manager
60
+ # -----------------
61
+ # config.audit_manager.model = MyAudit # default: Audit
62
+ # config.audit_manager.username_method = :username # default: :login
63
+ # config.audit_manager.keep_log = 30 # days
@@ -0,0 +1,31 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+ module Ixtlan
4
+ class Configurator
5
+
6
+ def self.symbolize_keys(h)
7
+ result = {}
8
+
9
+ h.each do |k, v|
10
+ v = ' ' if v.nil?
11
+ if v.is_a?(Hash)
12
+ result[k.to_sym] = symbolize_keys(v) unless v.size == 0
13
+ else
14
+ result[k.to_sym] = v unless k.to_sym == v.to_sym
15
+ end
16
+ end
17
+
18
+ result
19
+ end
20
+
21
+ def self.load(file)
22
+ if File.exists?(file)
23
+ symbolize_keys(YAML::load(ERB.new(IO.read(file)).result))
24
+ else
25
+ warn "no file #{file} to load - maybe the is a #{file}.example"
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ CONFIG = Ixtlan::Configurator.load(File.join(File.dirname(__FILE__), 'production.yml')) || {}
@@ -0,0 +1,8 @@
1
+ db:
2
+ database: production
3
+ username: worker
4
+ password: behappy
5
+ smtp:
6
+ host: mail.example.com
7
+ username: mailworker
8
+ password: secret
@@ -0,0 +1,2 @@
1
+ <h1>stale resource</h1>
2
+ <p>please reload resource and change it again</p>
@@ -0,0 +1,12 @@
1
+ module Rails
2
+ module Generators
3
+ class ModelGenerator < NamedBase #metagenerator
4
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
5
+ hook_for :orm, :required => true
6
+
7
+ if defined? Resty
8
+ hook_for :resty, :type => :boolean, :default => true
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ <%%= form_for(@<%= singular_table_name %><% if options[:singleton] -%>
2
+ , :url => <%= singular_table_name %>_path, :html => { :method => :put, :class => "edit_<%= singular_table_name %>", :id => "edit_<%= singular_table_name %>"}<% end -%>
3
+ ) do |f| %>
4
+ <%% if @<%= singular_table_name %>.errors.any? %>
5
+ <div id="error_explanation">
6
+ <h2><%%= pluralize(@<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
7
+
8
+ <ul>
9
+ <%% @<%= singular_table_name %>.errors.full_messages.each do |msg| %>
10
+ <li><%%= msg %></li>
11
+ <%% end %>
12
+ </ul>
13
+ </div>
14
+ <%% end %>
15
+
16
+ <% for attribute in attributes -%>
17
+ <div class="field"><!-- begin - <%= attribute.name %> -->
18
+ <%%= f.label :<%= attribute.name %> %><br />
19
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
20
+ </div><!-- end - <%= attribute.name %> -->
21
+ <% end -%>
22
+ <div class="actions">
23
+ <%%= f.submit %>
24
+ </div>
25
+ <%% end %>
@@ -0,0 +1,24 @@
1
+ <h1>Editing <%= singular_table_name %></h1>
2
+
3
+ <%%= render 'form' %>
4
+
5
+ <% if defined? ::Ixtlan::Guard -%>
6
+ <%% if allowed?(:<%= table_name %>, :show) %>
7
+ <% end -%>
8
+ <% if options[:singleton] -%>
9
+ <%%= link_to 'Show', <%= singular_table_name %>_path %>
10
+ <% else -%>
11
+ <%%= link_to 'Show', @<%= singular_table_name %> %>
12
+ <% end -%>
13
+ <% if defined? ::Ixtlan::Guard -%>
14
+ <%% end %>
15
+ <% end -%>
16
+ <% unless options[:singleton] -%>
17
+ <% if defined? ::Ixtlan::Guard -%>
18
+ <%% if allowed?(:<%= table_name %>, :index) %>
19
+ <% end -%>
20
+ | <%%= link_to 'Back', <%= index_helper %>_path %>
21
+ <% if defined? ::Ixtlan::Guard -%>
22
+ <%% end %>
23
+ <% end -%>
24
+ <% end -%>
@@ -0,0 +1,47 @@
1
+ <h1>Listing <%= plural_table_name %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <% for attribute in attributes -%>
6
+ <th><%= attribute.human_name %></th>
7
+ <% end -%>
8
+ <th></th>
9
+ <th></th>
10
+ <th></th>
11
+ </tr>
12
+
13
+ <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
14
+ <tr>
15
+ <% for attribute in attributes -%>
16
+ <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
17
+ <% end -%>
18
+ <% if defined? ::Ixtlan::Guard -%>
19
+ <%% if allowed?(:<%= table_name %>, :show) %>
20
+ <% end -%>
21
+ <td><%%= link_to 'Show', <%= singular_table_name %> %></td>
22
+ <% if defined? ::Ixtlan::Guard -%>
23
+ <%% end %>
24
+ <%% if allowed?(:<%= table_name %>, :update) %>
25
+ <% end -%>
26
+ <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td>
27
+ <% if defined? ::Ixtlan::Guard -%>
28
+ <%% end %>
29
+ <%% if allowed?(:<%= table_name %>, :destroy) %>
30
+ <% end -%>
31
+ <td><%%= link_to 'Destroy', <%= singular_table_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
32
+ <% if defined? ::Ixtlan::Guard -%>
33
+ <%% end %>
34
+ <% end -%>
35
+ </tr>
36
+ <%% end %>
37
+ </table>
38
+
39
+ <br />
40
+
41
+ <% if defined? ::Ixtlan::Guard -%>
42
+ <%% if allowed?(:<%= table_name %>, :create) %>
43
+ <% end -%>
44
+ <%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path %>
45
+ <% if defined? ::Ixtlan::Guard -%>
46
+ <%% end %>
47
+ <% end -%>
@@ -0,0 +1,19 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ <% attributes.select {|attr| ![:has_one, :has_many].include?(attr.type) }.each do |attribute| -%>
5
+ t.<%= attribute.type %> :<%= attribute.name %>
6
+ <% end -%>
7
+ <% if options[:timestamps] %>
8
+ t.timestamps
9
+ <% end -%>
10
+ <% if options[:modified_by] %>
11
+ t.references :modified_by
12
+ <% end -%>
13
+ end
14
+ end
15
+
16
+ def self.down
17
+ drop_table :<%= table_name %>
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ class <%= class_name %> < <%= parent_class_name.classify %>
2
+ <% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
3
+ belongs_to :<%= attribute.name %>
4
+ <% end -%>
5
+ <% attributes.select {|attr| [:has_one, :has_many].include?(attr.type) }.each do |attribute| -%>
6
+ <%= attribute.type %> :<%= attribute.name %>
7
+ <% end -%>
8
+ <% if options[:modified_by] -%>
9
+ belongs_to :modified_by, :class_name => "<%= options[:user_model] %>"
10
+ <% end -%>
11
+ <% if options[:singleton] -%>
12
+ def self.instance
13
+ self.first || self.new
14
+ end
15
+ <% end -%>
16
+ end
@@ -0,0 +1,11 @@
1
+ <h1>New <%= singular_table_name %></h1>
2
+
3
+ <%%= render 'form' %>
4
+
5
+ <% if defined? ::Ixtlan::Guard -%>
6
+ <%% if allowed?(:<%= table_name %>, :index) %>
7
+ <% end -%>
8
+ <%%= link_to 'Back', <%= index_helper %>_path %>
9
+ <% if defined? ::Ixtlan::Guard -%>
10
+ <%% end %>
11
+ <% end -%>
@@ -0,0 +1,30 @@
1
+ <p id="notice"><%%= notice %></p>
2
+
3
+ <% for attribute in attributes -%>
4
+ <p>
5
+ <b><%= attribute.human_name %>:</b>
6
+ <%%= @<%= singular_table_name %>.<%= attribute.name %> %>
7
+ </p>
8
+
9
+ <% end -%>
10
+
11
+ <% if defined? ::Ixtlan::Guard -%>
12
+ <%% if allowed?(:<%= table_name %>, :update) %>
13
+ <% end -%>
14
+ <% if options[:singleton] -%>
15
+ <%%= link_to 'Edit', edit_<%= singular_table_name %>_path %>
16
+ <% else -%>
17
+ <%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>) %>
18
+ <% end -%>
19
+ <% if defined? ::Ixtlan::Guard -%>
20
+ <%% end %>
21
+ <% end -%>
22
+ <% unless options[:singleton] -%>
23
+ <% if defined? ::Ixtlan::Guard -%>
24
+ <%% if allowed?(:<%= table_name %>, :index) %>
25
+ <% end -%>
26
+ | <%%= link_to 'Back', <%= index_helper %>_path %>
27
+ <% if defined? ::Ixtlan::Guard -%>
28
+ <%% end %>
29
+ <% end -%>
30
+ <% end -%>
@@ -0,0 +1,31 @@
1
+ require 'rails/generators/rails/resource/resource_generator'
2
+
3
+ module Rails
4
+ module Generators
5
+ class ScaffoldGenerator < ResourceGenerator #metagenerator
6
+ remove_hook_for :resource_controller
7
+ remove_class_option :actions
8
+
9
+ class_option :singleton, :type => :boolean, :default => false
10
+
11
+ hook_for :scaffold_controller, :required => true, :in => :scaffold_controller
12
+ hook_for :stylesheets
13
+
14
+ if defined? Resty
15
+ hook_for :resty, :type => :boolean, :default => true
16
+ end
17
+
18
+ def add_resource_route
19
+ return if options[:actions].present?
20
+ route_config = class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
21
+ if options[:singleton]
22
+ route_config << "resource :#{file_name}"
23
+ else
24
+ route_config << "resources :#{file_name.pluralize}"
25
+ end
26
+ route_config << " end" * class_path.size
27
+ route route_config
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,48 @@
1
+ require 'rails/generators/resource_helpers'
2
+ require 'rails/generators/named_base'
3
+
4
+ module ScaffoldController
5
+ module Generators
6
+ class ScaffoldControllerGenerator < ::Rails::Generators::NamedBase
7
+ include ::Rails::Generators::ResourceHelpers
8
+
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ check_class_collision :suffix => "Controller"
12
+
13
+ class_option :orm, :banner => "NAME", :type => :string, :required => true,
14
+ :desc => "ORM to generate the controller for"
15
+
16
+ class_option :singleton, :type => :boolean, :default => false
17
+
18
+ def create_controller_files
19
+ if options[:singleton]
20
+ template 'singleton_controller.rb', File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
21
+ else
22
+ template 'controller.rb', File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
23
+ end
24
+ end
25
+
26
+ hook_for :template_engine, :test_framework, :as => :scaffold, :in => :rails
27
+
28
+ # Invoke the helper using the controller name (pluralized)
29
+ hook_for :helper, :as => :scaffold, :in => :rails do |invoked|
30
+ invoke invoked, [ controller_name ]
31
+ end
32
+
33
+ if defined? ::Resty
34
+ # resty gwt controller
35
+ hook_for :resty, :type => :boolean, :default => true do |controller|
36
+ invoke controller, [class_name]
37
+ end
38
+ end
39
+
40
+ if defined? ::Ixtlan::Guard
41
+ # allow the ixtlan guards to be generated
42
+ hook_for :guard, :type => :boolean, :default => true do |controller|
43
+ invoke controller, [class_name]
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,99 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+ # GET <%= route_url %>
3
+ # GET <%= route_url %>.xml
4
+ # GET <%= route_url %>.json
5
+ def index
6
+ @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
7
+
8
+ respond_to do |format|
9
+ format.html # index.html.erb
10
+ format.xml { render :xml => @<%= plural_table_name %> }
11
+ format.json { render :json => @<%= plural_table_name %> }
12
+ end
13
+ end
14
+
15
+ # GET <%= route_url %>/1
16
+ # GET <%= route_url %>/1.xml
17
+ # GET <%= route_url %>/1.json
18
+ def show
19
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
20
+
21
+ respond_to do |format|
22
+ format.html # show.html.erb
23
+ format.xml { render :xml => @<%= singular_table_name %> }
24
+ format.json { render :json => @<%= singular_table_name %> }
25
+ end
26
+ end
27
+
28
+ # GET <%= route_url %>/new
29
+ def new
30
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
31
+ end
32
+
33
+ # GET <%= route_url %>/1/edit
34
+ def edit
35
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
36
+ end
37
+
38
+ # POST <%= route_url %>
39
+ # POST <%= route_url %>.xml
40
+ # POST <%= route_url %>.json
41
+ def create
42
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "params[:#{singular_table_name}]") %>
43
+ <% unless options[:modified_by] -%>
44
+ @<%= singular_table_name %>.current_user = current_user
45
+ <% end -%>
46
+
47
+ respond_to do |format|
48
+ if @<%= orm_instance.save %>
49
+ format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully created.') }
50
+ format.xml { render :xml => @<%= singular_table_name %>, :status => :created, :location => @<%= singular_table_name %> }
51
+ format.json { render :json => @<%= singular_table_name %>, :status => :created, :location => @<%= singular_table_name %> }
52
+ else
53
+ format.html { render :action => "new" }
54
+ format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
55
+ format.json { render :json => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
56
+ end
57
+ end
58
+ end
59
+
60
+ # PUT <%= route_url %>/1
61
+ # PUT <%= route_url %>/1.xml
62
+ # PUT <%= route_url %>/1.json
63
+ def update
64
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
65
+ <% if options[:modified_by] -%>
66
+ @<%= singular_table_name %>.current_user = current_user
67
+ <% end -%>
68
+
69
+ respond_to do |format|
70
+ if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %>
71
+ format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully updated.') }
72
+ format.xml { render :xml => @<%= singular_table_name %> }
73
+ format.json { render :json => @<%= singular_table_name %> }
74
+ else
75
+ format.html { render :action => "edit" }
76
+ format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
77
+ format.json { render :json => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
78
+ end
79
+ end
80
+ end
81
+
82
+ # DELETE <%= route_url %>/1
83
+ # DELETE <%= route_url %>/1.xml
84
+ # DELETE <%= route_url %>/1.json
85
+ def destroy
86
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
87
+ <% if options[:modified_by] -%>
88
+ @<%= singular_table_name %>.current_user = current_user
89
+ <% end -%>
90
+
91
+ @<%= orm_instance.destroy %>
92
+
93
+ respond_to do |format|
94
+ format.html { redirect_to(<%= index_helper %>_url) }
95
+ format.xml { head :ok }
96
+ format.json { head :ok }
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,43 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+
3
+ # GET <%= route_url %>
4
+ # GET <%= route_url %>.xml
5
+ # GET <%= route_url %>.json
6
+ def show
7
+ @<%= singular_table_name %> = <%= class_name %>.instance
8
+
9
+ respond_to do |format|
10
+ format.html # show.html.erb
11
+ format.xml { render :xml => @<%= singular_table_name %> }
12
+ format.json { render :json => @<%= singular_table_name %> }
13
+ end
14
+ end
15
+
16
+ # GET <%= route_url %>/edit
17
+ def edit
18
+ @<%= singular_table_name %> = <%= class_name %>.instance
19
+ end
20
+
21
+ # PUT <%= route_url %>
22
+ # PUT <%= route_url %>.xml
23
+ # PUT <%= route_url %>.json
24
+ def update
25
+ @<%= singular_table_name %> = <%= class_name %>.instance
26
+ <% orm_class.find(class_name)
27
+ if options[:modified_by] -%>
28
+ @<%= singular_table_name %>.current_user = current_user
29
+ <% end -%>
30
+
31
+ respond_to do |format|
32
+ if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %>
33
+ format.html { redirect_to(<%= singular_table_name %>_path, :notice => '<%= human_name %> was successfully updated.') }
34
+ format.xml { render :xml => @<%= singular_table_name %> }
35
+ format.json { render :json => @<%= singular_table_name %> }
36
+ else
37
+ format.html { render :action => "edit" }
38
+ format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
39
+ format.json { render :json => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,86 @@
1
+ module Ixtlan
2
+ module Core
3
+ module CacheHeaders
4
+
5
+ protected
6
+
7
+ # Date: <ServercurrentDate>
8
+ # Expires: Fri, 01 Jan 1990 00:00:00 GMT
9
+ # Pragma: no-cache
10
+ # Cache-control: no-cache, must-revalidate
11
+ def no_caching(no_store = true)
12
+ if cachable_response?
13
+ response.headers["Date"] = timestamp
14
+ response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
15
+ response.headers["Pragma"] = "no-cache"
16
+ response.headers["Cache-Control"] = "no-cache, must-revalidate" + (", no-store" if no_store).to_s
17
+ end
18
+ end
19
+
20
+ # Date: <ServercurrentDate>
21
+ # Expires: Fri, 01 Jan 1990 00:00:00 GMT
22
+ # Cache-control: private, max-age=<1dayInSeconds>
23
+ def only_browser_can_cache(no_store = false, max_age_in_seconds = 0)
24
+ if cachable_response?
25
+ response.headers["Date"] = timestamp
26
+ response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 UTC"
27
+ response.headers["Cache-Control"] = "private, max-age=#{max_age_in_seconds}" + (", no-store" if no_store).to_s
28
+ end
29
+ end
30
+
31
+ # Date: <ServercurrentDate>
32
+ # Expires: <ServerCurrentDate + 1month>
33
+ # Cache-control: public, max-age=<1month>
34
+ def allow_browser_and_proxy_to_cache(no_store = false, max_age_in_seconds = 0)
35
+ if cachable_response?
36
+ now = Time.now
37
+ response.headers["Date"] = timestamp(now)
38
+ response.headers["Expires"] = timestamp(now + max_age_in_seconds)
39
+ response.headers["Cache-Control"] = "public, max-age=#{max_age_in_seconds}" + (", no-store" if no_store).to_s
40
+ end
41
+ end
42
+
43
+ def cache_headers
44
+ if(respond_to?(:current_user) && current_user)
45
+ case self.class.instance_variable_get(:@mode)
46
+ when :private
47
+ no_caching(self.class.instance_variable_get(:@no_store))
48
+ when :protected
49
+ only_browser_can_cache(self.class.instance_variable_get(:@no_store))
50
+ when :public
51
+ allow_browser_and_proxy_to_cache(self.class.instance_variable_get(:@no_store))
52
+ end
53
+ # else
54
+ # allow_browser_and_proxy_to_cache(self.class.instance_variable_get(:@no_store))
55
+ end
56
+ end
57
+
58
+ def self.included(base)
59
+ base.class_eval do
60
+ def self.cache_headers(mode = nil, no_store = true)
61
+ if(mode)
62
+ raise "supported modi are :private, :protected and :public" unless [:private, :protected, :public].member? mode.to_sym
63
+ @mode = mode
64
+ end
65
+ @no_store = no_store
66
+ end
67
+ alias :render_old :render
68
+ def render(*args)
69
+ cache_headers
70
+ render_old(*args)
71
+ end
72
+ end
73
+ end
74
+
75
+ private
76
+ def cachable_response?
77
+ request.method == :get &&
78
+ [200, 203, 206, 300, 301].member?(response.status)
79
+ end
80
+
81
+ def timestamp(now = Time.now)
82
+ now.utc.strftime "%a, %d %b %Y %H:%M:%S %Z"
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,43 @@
1
+ module Ixtlan
2
+ module Core
3
+ module ConfigurationManager
4
+
5
+ def self.included(model)
6
+ model.send :include, Slf4r::Logger
7
+ model.after_save :fire_on_change
8
+ raise "configuration class must have instance method" unless model.respond_to? :instance
9
+ model.class_eval do
10
+ class << self
11
+ alias :instance_old :instance
12
+ def instance
13
+ Thread.current[:ixtlan_configuration] ||= instance_old
14
+ end
15
+ def clear_instance
16
+ Thread.current[:ixtlan_configruation] = nil
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ def register(name, &block)
23
+ raise "need block" unless block
24
+ logger.info{"register config for: #{name}"}
25
+ registry[name.to_sym] = block
26
+ end
27
+
28
+ def fire_on_change
29
+ registry.each do |name, callback|
30
+ logger.debug{ "call #{name}" }
31
+ callback.call(self)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def registry
38
+ @registry ||= {}
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ module Ixtlan
2
+ module Core
3
+ class ConfigurationRack
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ model = Rails.application.config.configuration_model
10
+ # configure all registered components with current config
11
+ model.instance.fire_on_change if model
12
+ result = @app.call(env)
13
+ model.clear_instance if model
14
+ result
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,48 @@
1
+ module Ixtlan
2
+ module Core
3
+ module Controllers
4
+ module ConfigurationController
5
+
6
+ # GET /configuration
7
+ # GET /configuration.xml
8
+ # GET /configuration.json
9
+ def show
10
+ @config = Rails.application.config.configuration_model.instance
11
+
12
+ respond_to do |format|
13
+ format.html # index.html.erb
14
+ format.xml { render :xml => @config }
15
+ format.json { render :json => @config }
16
+ end
17
+ end
18
+
19
+ # GET configuration/edit
20
+ def edit
21
+ @config = Rails.application.config.configuration_model.instance
22
+ end
23
+
24
+ # PUT configuration
25
+ # PUT configuration.xml
26
+ def update
27
+ @config = Rails.application.config.configuration_model.instance
28
+
29
+ if @config.respond_to? :current_user && respond_to? :current_user
30
+ @config.current_user = current_user
31
+ end
32
+
33
+ respond_to do |format|
34
+ if @config.update_attributes
35
+ format.html { redirect_to(@config, :notice => 'configuration was successfully updated.') }
36
+ format.xml { render :xml => @config }
37
+ format.json { render :json => @config }
38
+ else
39
+ format.html { render :action => "edit" }
40
+ format.xml { render :xml => @config.errors, :status => :unprocessable_entity }
41
+ format.json { render :json => @config.errors, :status => :unprocessable_entity }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,47 @@
1
+ require 'ixtlan/core/cache_headers'
2
+ require 'ixtlan/core/configuration_rack'
3
+ require 'ixtlan/core/configuration_manager'
4
+
5
+ module Ixtlan
6
+ module Core
7
+ class Railtie < Rails::Railtie
8
+ config.generators do
9
+ require 'rails/generators'
10
+
11
+ templates = File.expand_path('../../../generators/rails/templates', __FILE__)
12
+
13
+ require 'rails/generators/erb/scaffold/scaffold_generator'
14
+ Erb::Generators::ScaffoldGenerator.source_paths.insert(0, templates)
15
+ Erb::Generators::ScaffoldGenerator.class_option :singleton, :type => :boolean, :default => false
16
+ Erb::Generators::ScaffoldGenerator.class_eval do
17
+
18
+ protected
19
+ alias :available_views_old :available_views
20
+ def available_views
21
+ if options[:singleton]
22
+ %w(edit show _form)
23
+ else
24
+ available_views_old
25
+ end
26
+ end
27
+ end
28
+
29
+ require 'rails/generators/active_record/model/model_generator'
30
+ ActiveRecord::Generators::ModelGenerator.source_paths.insert(0, templates)
31
+ ActiveRecord::Generators::ModelGenerator.class_option :singleton, :type => :boolean, :default => false
32
+ end
33
+
34
+ config.before_configuration do |app|
35
+ app.config.class.class_eval do
36
+ attr_accessor :configuration_model
37
+ def configuration_model=(clazz)
38
+ clazz.send(:include, Ixtlan::Core::ConfigurationManager) #unless clazz.kind_of?(Ixtlan::Core::ConfigurationManager)
39
+ @configuration_model = clazz
40
+ end
41
+ end
42
+ ::ActionController::Base.send(:include, Ixtlan::Core::CacheHeaders)
43
+ app.config.middleware.use Ixtlan::Core::ConfigurationRack
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ if defined?(Rails)
2
+ require 'ixtlan/core/railtie'
3
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ixtlan-core
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - mkristian
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-03-01 00:00:00 +05:30
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rails
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 3
29
+ - 0
30
+ - 1
31
+ version: 3.0.1
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rspec
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 2
43
+ - 0
44
+ - 1
45
+ version: 2.0.1
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: cucumber
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ - 9
58
+ - 4
59
+ version: 0.9.4
60
+ type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ - 8
72
+ - 7
73
+ version: 0.8.7
74
+ type: :development
75
+ version_requirements: *id004
76
+ description: base for some gems related to protect privacy and increase security along some other utils
77
+ email:
78
+ - m.kristian@web.de
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files: []
84
+
85
+ files:
86
+ - README.textile
87
+ - features/step_definitions/simple_steps.rb
88
+ - features/generators.feature
89
+ - lib/ixtlan-core.rb
90
+ - lib/generators/model/model_generator.rb
91
+ - lib/generators/scaffold/scaffold_generator.rb
92
+ - lib/generators/ixtlan/base.rb
93
+ - lib/generators/ixtlan/configuration_scaffold/configuration_scaffold_generator.rb
94
+ - lib/generators/ixtlan/setup/setup_generator.rb
95
+ - lib/generators/ixtlan/setup/templates/gitignore
96
+ - lib/generators/ixtlan/setup/templates/error_with_session.html.erb
97
+ - lib/generators/ixtlan/setup/templates/production.yml.example
98
+ - lib/generators/ixtlan/setup/templates/preinitializer.rb
99
+ - lib/generators/ixtlan/setup/templates/error.html.erb
100
+ - lib/generators/ixtlan/setup/templates/database.yml.example
101
+ - lib/generators/ixtlan/setup/templates/application_layout.html.erb
102
+ - lib/generators/ixtlan/setup/templates/initializer.rb
103
+ - lib/generators/ixtlan/setup/templates/stale.html.erb
104
+ - lib/generators/ixtlan/configuration_model/configuration_model_generator.rb
105
+ - lib/generators/scaffold_controller/scaffold_controller_generator.rb
106
+ - lib/generators/scaffold_controller/templates/controller.rb
107
+ - lib/generators/scaffold_controller/templates/singleton_controller.rb
108
+ - lib/generators/rails/templates/index.html.erb
109
+ - lib/generators/rails/templates/new.html.erb
110
+ - lib/generators/rails/templates/model.rb
111
+ - lib/generators/rails/templates/show.html.erb
112
+ - lib/generators/rails/templates/edit.html.erb
113
+ - lib/generators/rails/templates/migration.rb
114
+ - lib/generators/rails/templates/_form.html.erb
115
+ - lib/ixtlan/core/railtie.rb
116
+ - lib/ixtlan/core/configuration_manager.rb
117
+ - lib/ixtlan/core/cache_headers.rb
118
+ - lib/ixtlan/core/configuration_rack.rb
119
+ - lib/ixtlan/core/controllers/configuration_controller.rb
120
+ has_rdoc: true
121
+ homepage: http://github.com/mkristian/ixtlan-core
122
+ licenses: []
123
+
124
+ post_install_message:
125
+ rdoc_options:
126
+ - --main
127
+ - README.textile
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ segments:
135
+ - 0
136
+ version: "0"
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ segments:
142
+ - 0
143
+ version: "0"
144
+ requirements: []
145
+
146
+ rubyforge_project:
147
+ rubygems_version: 1.3.6
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: cache header control, dynamic configuration, and rails generator templates
151
+ test_files: []
152
+