ixtlan-core 0.1.0

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