alfa 0.0.5.pre → 0.0.6.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dummy/project/.gitignore +16 -0
- data/dummy/project/.ruby-version +1 -0
- data/dummy/project/CHANGELOG +0 -0
- data/dummy/project/Gemfile.source +7 -2
- data/dummy/project/README +0 -0
- data/dummy/project/apps/admin/layouts/base.haml +10 -0
- data/dummy/project/apps/admin/layouts/index.haml.source +7 -0
- data/dummy/project/apps/admin/templates/default/index.haml +1 -0
- data/dummy/project/apps/frontend/layouts/base.haml +10 -0
- data/dummy/project/apps/frontend/layouts/index.haml.source +7 -0
- data/dummy/project/apps/frontend/templates/default/{index.tpl → index.haml} +0 -0
- data/dummy/project/config/db.rb +15 -0
- data/dummy/project/config/passwords/.gitignore.source +3 -0
- data/dummy/project/config/passwords/db-main.yml.source +8 -0
- data/dummy/project/config/passwords/secrets.sample.yml +2 -0
- data/dummy/project/config/passwords/secrets.yml.source +2 -0
- data/dummy/project/config/web_application.rb +1 -0
- data/dummy/project/db/main/migrations/.keep +0 -0
- data/dummy/project/db/main/models/.keep +0 -0
- data/dummy/project/db/main/schema/.keep +0 -0
- data/dummy/project/db/main/seed.rb +0 -0
- data/dummy/project/log/.keep +0 -0
- data/dummy/project/public/.htaccess +13 -0
- data/dummy/project/tasks/.keep +0 -0
- data/dummy/project/test/.keep +0 -0
- data/lib/alfa/application.rb +21 -1
- data/lib/alfa/commands/new.rb +14 -9
- data/lib/alfa/config.rb +3 -2
- data/lib/alfa/controller.rb +19 -104
- data/lib/alfa/database.rb +2 -1
- data/lib/alfa/exceptions.rb +5 -0
- data/lib/alfa/logger.rb +4 -3
- data/lib/alfa/resourcer.rb +29 -0
- data/lib/alfa/router.rb +34 -14
- data/lib/alfa/snippeter.rb +42 -0
- data/lib/alfa/support/common.rb +195 -0
- data/lib/alfa/support/nil_operations.rb +207 -0
- data/lib/alfa/support/time.rb +5 -0
- data/lib/alfa/support.rb +3 -135
- data/lib/alfa/tasks/assets.rake +16 -0
- data/lib/alfa/tasks/db.rake +169 -0
- data/lib/alfa/tasks/generators.rake +80 -0
- data/lib/alfa/tasks.rb +4 -0
- data/lib/alfa/tfile.rb +1 -1
- data/lib/alfa/user.rb +41 -6
- data/lib/alfa/web_application.rb +96 -31
- data/lib/alfa/wrapper.rb +155 -0
- data/lib/alfa.rb +0 -2
- data/lib/rack/file_alfa.rb +2 -1
- data/lib/sequel/extensions/igrep.rb +19 -0
- data/lib/sequel/extensions/with_pks.rb +15 -0
- data/lib/template-inheritance/alfa_helpers.rb +106 -25
- data/lib/tilt/alfa_patch.rb +1 -1
- data/test/data/test_router/1/apps/frontend/routes.rb +1 -0
- data/test/data/test_router/2/apps/frontend/routes.rb +1 -0
- data/test/data/test_web_application/apps/admin/controllers/second.rb +5 -0
- data/test/data/test_web_application/apps/admin/layouts/default.haml +1 -0
- data/test/data/test_web_application/apps/admin/layouts/default.tpl +1 -0
- data/test/data/test_web_application/apps/admin/routes.rb +1 -0
- data/test/data/test_web_application/apps/admin/templates/default/test_04.haml +1 -0
- data/test/data/test_web_application/apps/admin/templates/default/test_04.tpl +1 -0
- data/test/data/test_web_application/apps/admin/templates/default/test_08.haml +2 -0
- data/test/data/test_web_application/apps/admin/templates/default/test_08a.haml +1 -0
- data/test/data/test_web_application/apps/admin/templates/second/index.haml +1 -0
- data/test/data/test_web_application/apps/frontend/controllers/second.rb +5 -0
- data/test/data/test_web_application/apps/frontend/layouts/default.haml +1 -0
- data/test/data/test_web_application/apps/frontend/layouts/default.tpl +1 -0
- data/test/data/test_web_application/apps/frontend/routes.rb +1 -0
- data/test/data/test_web_application/apps/frontend/templates/default/bar.haml +0 -0
- data/test/data/test_web_application/apps/frontend/templates/default/bar.tpl +0 -0
- data/test/data/test_web_application/apps/frontend/templates/default/frontend_only.haml +0 -0
- data/test/data/test_web_application/apps/frontend/templates/default/frontend_only.tpl +0 -0
- data/test/data/test_web_application/apps/frontend/templates/default/index.haml +0 -0
- data/test/data/test_web_application/apps/frontend/templates/default/index.tpl +0 -0
- data/test/data/test_web_application/apps/frontend/templates/default/test_04.haml +1 -0
- data/test/data/test_web_application/apps/frontend/templates/default/test_04.tpl +1 -0
- data/test/data/test_web_application/apps/frontend/templates/default/test_08.haml +2 -0
- data/test/data/test_web_application/apps/frontend/templates/default/test_08a.haml +1 -0
- data/test/data/test_web_application/apps/frontend/templates/second/index.haml +1 -0
- data/test/test_config.rb +2 -2
- data/test/test_controller.rb +13 -3
- data/test/test_router.rb +13 -6
- data/test/test_ruby_core.rb +32 -0
- data/test/test_support.rb +152 -11
- data/test/test_web_application.rb +7 -0
- data/version.rb +1 -1
- metadata +100 -16
- data/lib/alfa/database/mysql.rb +0 -107
- data/lib/alfa/models/base.rb +0 -7
- data/lib/alfa/models/base_sql.rb +0 -9
- data/lib/alfa/models/dummy.rb +0 -7
- data/lib/alfa/models/mysql.rb +0 -62
- data/lib/alfa/models.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42b04d75d9c3ed910907e1c46163b85226939122
|
4
|
+
data.tar.gz: ffbf8a3228d0271f6c8a631ad3f626484c7ec4ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0625ca1aba2e5eb757cbd0d613fa4b2712c4c6c130093cf39c43e9b9c21fd8948bfaca6f6a8bbe2d3cc8876dbf8d637afc61f29835eeed22d3bcf309d5737f0f
|
7
|
+
data.tar.gz: e4195b642f031804e08eca399335b95b48604d7a98d0c64eca640c322f4eb3bf3fada7e3a36a3d81c438bf928a932c077c3413b7e1a6ebe6e58b7cb5de6332cb
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
2
|
+
|
3
|
+
/.bundle/
|
4
|
+
/tmp/
|
5
|
+
/log/*.log
|
6
|
+
/public/~assets/
|
7
|
+
|
8
|
+
# IDE settings (Eclipse)
|
9
|
+
/.project
|
10
|
+
/.classpath
|
11
|
+
|
12
|
+
# IDE settings (JetBrains RubyMine)
|
13
|
+
*.iml
|
14
|
+
*.ipr
|
15
|
+
*.iws
|
16
|
+
/.idea/
|
@@ -0,0 +1 @@
|
|
1
|
+
2.1.1
|
File without changes
|
@@ -2,5 +2,10 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gem 'alfa', '#{ALFA_VERSION}'
|
4
4
|
|
5
|
-
#
|
6
|
-
gem 'mysql2', '~> 0.3'
|
5
|
+
# Use mysql2 as database adapter
|
6
|
+
gem 'mysql2', '~> 0.3', '>= 0.3.15'
|
7
|
+
|
8
|
+
# Uncomment following gems if necessary:
|
9
|
+
#
|
10
|
+
# gem 'thin'
|
11
|
+
# gem 'redcarpet'
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
apps/admin/default#index
|
File without changes
|
data/dummy/project/config/db.rb
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
require 'alfa/database'
|
2
2
|
require 'yaml'
|
3
3
|
|
4
|
+
# Read more about the timestamps plugin:
|
5
|
+
# http://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins/Timestamps.html
|
6
|
+
Sequel::Model.plugin :timestamps, update_on_create: true
|
7
|
+
|
8
|
+
# Read more about prepared statements and the plugin:
|
9
|
+
# http://sequel.jeremyevans.net/rdoc/files/doc/prepared_statements_rdoc.html
|
10
|
+
# http://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins/PreparedStatements.html
|
11
|
+
# Sequel::Model.plugin :prepared_statements
|
12
|
+
|
13
|
+
# Read more about available plugins:
|
14
|
+
# http://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins.html
|
15
|
+
|
16
|
+
|
4
17
|
# Main database for application private use
|
5
18
|
module DB
|
6
19
|
Main = Sequel.connect(YAML.load(File.open(File.expand_path('../passwords/db-main.yml', __FILE__))).symbolize_keys[:dsn], :encoding=>'utf8')
|
@@ -9,3 +22,5 @@ end
|
|
9
22
|
Dir[File.join(PROJECT_ROOT, 'db/main/models/*.rb')].each do |f|
|
10
23
|
require f
|
11
24
|
end
|
25
|
+
|
26
|
+
Sequel.extension :blank
|
@@ -9,6 +9,7 @@ module Project
|
|
9
9
|
config[:run_mode] = :development # :development or :production or :test
|
10
10
|
config[:log][:file] = File.join(PROJECT_ROOT, 'log/web.log')
|
11
11
|
config[:serve_static] = true
|
12
|
+
config[:session][:secret] = YAML.load(File.open(File.expand_path('../passwords/secrets.yml', __FILE__))).symbolize_keys[:session_secret]
|
12
13
|
end
|
13
14
|
|
14
15
|
WebApplication.init!
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Options -Indexes
|
2
|
+
|
3
|
+
<IfModule mod_expires.c>
|
4
|
+
ExpiresActive on
|
5
|
+
ExpiresByType image/gif A604800
|
6
|
+
ExpiresByType image/png A604800
|
7
|
+
ExpiresByType image/jpg A604800
|
8
|
+
ExpiresByType image/jpeg A604800
|
9
|
+
ExpiresByType image/x-icon A604800
|
10
|
+
ExpiresByType image/vnd.microsoft.icon A604800
|
11
|
+
ExpiresByType text/css A604800
|
12
|
+
ExpiresByType application/javascript A604800
|
13
|
+
</IfModule>
|
File without changes
|
File without changes
|
data/lib/alfa/application.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'alfa/logger'
|
2
2
|
require 'alfa/config'
|
3
3
|
require 'alfa/exceptions'
|
4
|
+
require 'alfa/user'
|
4
5
|
|
5
6
|
Encoding.default_external = 'utf-8'
|
6
7
|
Encoding.default_internal = 'utf-8'
|
@@ -36,7 +37,7 @@ module Alfa
|
|
36
37
|
@logger.info " DOCUMENT_ROOT: #{@config[:document_root]}\n"
|
37
38
|
@log_file.flush
|
38
39
|
ObjectSpace.define_finalizer(@logger, Proc.new {@logger.info "Application (pid=#{$$}) stopped at #{DateTime.now}\n\n"})
|
39
|
-
@config[:db].each_value { |db| db[:instance].
|
40
|
+
@config[:db].each_value { |db| db[:instance].logger = @logger }
|
40
41
|
else
|
41
42
|
@logger = Alfa::NullLogger.new
|
42
43
|
end
|
@@ -47,11 +48,30 @@ module Alfa
|
|
47
48
|
def self.load_tasks
|
48
49
|
VARS[:rakeapp_instance] = self
|
49
50
|
require 'alfa/tasks'
|
51
|
+
Dir[File.join(@config[:project_root], 'tasks', '*.rake')].each do |f|
|
52
|
+
Kernel.load f
|
53
|
+
end
|
50
54
|
end
|
51
55
|
|
52
56
|
|
53
57
|
def self.verify_config
|
54
58
|
raise Exceptions::E001.new('config[:project_root] should be defined') unless @config[:project_root]
|
55
59
|
end
|
60
|
+
|
61
|
+
|
62
|
+
def self.try_register(login, password)
|
63
|
+
@config[:db][:main][:instance].transaction do
|
64
|
+
unless User.first(:login=>login)
|
65
|
+
@logger.portion do |l|
|
66
|
+
salt = SecureRandom.hex(5)
|
67
|
+
passhash = Digest::MD5.hexdigest("#{salt}#{password}")
|
68
|
+
User.create(:login=>login, :salt=>salt, :passhash=>passhash)
|
69
|
+
l.info("created new user login=#{login}, password=***, salt=#{salt}, passhash=#{passhash}")
|
70
|
+
end
|
71
|
+
return true, "Registration done"
|
72
|
+
end
|
73
|
+
return false, "User with login #{login} already exists"
|
74
|
+
end
|
75
|
+
end
|
56
76
|
end
|
57
77
|
end
|
data/lib/alfa/commands/new.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require File.expand_path('../../../../version', __FILE__)
|
2
2
|
require 'fileutils'
|
3
3
|
require 'alfa/support'
|
4
|
+
require 'securerandom'
|
4
5
|
|
5
6
|
PROJECT_NAME = $*[1]
|
7
|
+
SESSION_SECRET = SecureRandom.base64(24)
|
6
8
|
|
7
9
|
sr = {
|
8
10
|
'#{ALFA_VERSION}' => ALFA_VERSION,
|
9
11
|
'#{PROJECT_NAME}' => PROJECT_NAME,
|
12
|
+
'#{SESSION_SECRET}' => SESSION_SECRET
|
10
13
|
}
|
11
14
|
|
12
15
|
target_dir = File.join(Dir.pwd, PROJECT_NAME)
|
@@ -38,12 +41,14 @@ ensure
|
|
38
41
|
puts ""
|
39
42
|
end
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
puts "Run 'cd #{PROJECT_NAME} && bundle install' manually"
|
45
|
+
|
46
|
+
# begin
|
47
|
+
# print "Bundle install... "
|
48
|
+
# FileUtils.cd PROJECT_NAME
|
49
|
+
# `bundle install`
|
50
|
+
# print "done"
|
51
|
+
# ensure
|
52
|
+
# FileUtils.cd '..'
|
53
|
+
# puts ""
|
54
|
+
# end
|
data/lib/alfa/config.rb
CHANGED
@@ -4,17 +4,18 @@ module Alfa
|
|
4
4
|
def initialize
|
5
5
|
self[:db] = {}
|
6
6
|
self[:log] = {}
|
7
|
+
self[:session] = {key: 'session', secret: nil}
|
7
8
|
end
|
8
9
|
|
9
10
|
def []=(key, value)
|
10
|
-
if [:db, :log].include? key
|
11
|
+
if [:db, :log, :session].include? key
|
11
12
|
raise "key :#{key} should include Enumerable" unless value.class.included_modules.include? Enumerable
|
12
13
|
end
|
13
14
|
super
|
14
15
|
end
|
15
16
|
|
16
17
|
def store(key, value)
|
17
|
-
if [:db, :log].include? key
|
18
|
+
if [:db, :log, :session].include? key
|
18
19
|
raise "key :#{key} should include Enumerable" unless value.class.included_modules.include? Enumerable
|
19
20
|
end
|
20
21
|
super
|
data/lib/alfa/controller.rb
CHANGED
@@ -1,124 +1,39 @@
|
|
1
|
-
require 'alfa/
|
2
|
-
require 'alfa/exceptions'
|
1
|
+
require 'alfa/wrapper'
|
3
2
|
|
4
3
|
module Alfa
|
5
4
|
class Controller
|
6
|
-
|
5
|
+
include Alfa::WrapperMethods
|
7
6
|
|
8
|
-
|
9
|
-
Hash[instance_variables.map { |name| [name.to_sym, instance_variable_get(name)] } ]
|
10
|
-
end
|
11
|
-
|
12
|
-
def _clear_instance_variables
|
13
|
-
instance_variables.each {|name| remove_instance_variable(name)}
|
14
|
-
end
|
15
|
-
|
16
|
-
def href(*o)
|
17
|
-
kwargs = _extract_href_params(*o)
|
18
|
-
@application.routes.href(kwargs)
|
19
|
-
end
|
20
|
-
|
21
|
-
alias :href_to :href
|
22
|
-
|
23
|
-
def _extract_href_params(*o)
|
24
|
-
args, kwargs = Support.args_kwargs(*o)
|
25
|
-
if args.any?
|
26
|
-
if args.first.is_a?(Symbol)
|
27
|
-
kwargs[:action] = args.first
|
28
|
-
else
|
29
|
-
kwargs.merge! _string_to_aca(args.first.to_s)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
kwargs = {:app=>@app_sym}.merge kwargs
|
33
|
-
kwargs = {:controller=>@c_sym}.merge kwargs if kwargs[:action]
|
34
|
-
kwargs
|
35
|
-
end
|
36
|
-
|
37
|
-
# Convert string to App-Controller-Action hash
|
38
|
-
# 'app*controller#action'
|
39
|
-
def _string_to_aca(str)
|
40
|
-
res = {}
|
41
|
-
s1 = str.split('@')
|
42
|
-
raise Exceptions::E004.new("E004: Bad href argument #{str}: it should contain at most one @ symbol") if s1.length > 2
|
43
|
-
res[:app] = s1.last.to_sym if s1.length > 1
|
44
|
-
s2 = s1.first.split('#')
|
45
|
-
raise Exceptions::E004.new("E004: Bad href argument #{str}: it should contain at most one # symbol") if s2.length > 2
|
46
|
-
res[:controller] = s2.first.to_sym if s2.length > 1
|
47
|
-
res[:action] = s2.last.to_sym if s2.length > 0
|
48
|
-
res
|
49
|
-
end
|
7
|
+
attr_accessor :application, :request, :config, :app_sym, :c_sym, :params, :resourcer, :route
|
50
8
|
|
51
|
-
|
52
|
-
|
53
|
-
@request.session
|
9
|
+
def initialize(route: nil)
|
10
|
+
@route = route
|
54
11
|
end
|
55
12
|
|
56
|
-
|
57
|
-
|
58
|
-
@user ||= (
|
59
|
-
if @request.session[:user_id] && (u = @application.config[:db][:main][:instance][:users].first(id: @request.session[:user_id]))
|
60
|
-
User.new(u)
|
61
|
-
else
|
62
|
-
GuestUser
|
63
|
-
end
|
64
|
-
)
|
13
|
+
def self.__options
|
14
|
+
@__options ||= {}
|
65
15
|
end
|
66
16
|
|
67
|
-
|
68
|
-
|
69
|
-
user.grant?(grant)
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
[300, 301, 302, 303].each do |code|
|
74
|
-
define_method ("redirect_#{code}".to_sym) do |url|
|
75
|
-
@application.redirect(url, code)
|
76
|
-
end
|
17
|
+
def render(type)
|
18
|
+
self.class.options(caller_locations(1, 1)[0].label.to_sym, {render: type})
|
77
19
|
end
|
78
20
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
def try_login(username, password)
|
83
|
-
u = @application.config[:db][:main][:instance][:users].first(login: username)
|
84
|
-
raise "No such login: #{username}" unless u
|
85
|
-
if u[:passhash] == Digest::MD5.hexdigest("#{u[:salt]}#{password}")
|
86
|
-
# success
|
87
|
-
session[:user_id] = u[:id]
|
88
|
-
return true
|
89
|
-
else
|
90
|
-
# fail
|
91
|
-
session[:user_id] = nil
|
92
|
-
raise 'login fail'
|
93
|
-
return false
|
94
|
-
end
|
21
|
+
def self.options(method, opts)
|
22
|
+
__options[method.to_sym] = __options[method.to_sym] ? __options[method.to_sym].merge(opts) : opts
|
95
23
|
end
|
96
24
|
|
97
|
-
|
98
|
-
|
99
|
-
@config[:db][:main][:instance].transaction do
|
100
|
-
unless @config[:db][:main][:instance][:users].first(:login=>username)
|
101
|
-
@logger.portion do |l|
|
102
|
-
salt = SecureRandom.hex(5)
|
103
|
-
passhash = Digest::MD5.hexdigest("#{salt}#{password}")
|
104
|
-
@config[:db][:main][:instance][:users].insert(:login=>username, :salt=>salt, :passhash=>passhash)
|
105
|
-
l.info("create new user login=#{username}, password=#{password}, salt=#{salt}, passhash=#{passhash}")
|
106
|
-
end
|
107
|
-
return true, "Registration done"
|
108
|
-
end
|
109
|
-
return false, "User with login #{username} already exists"
|
110
|
-
end
|
25
|
+
def set_options(opts = {})
|
26
|
+
self.class.options(caller_locations(1, 1)[0].label.to_sym, opts)
|
111
27
|
end
|
112
28
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
@user = GuestUser
|
29
|
+
def self.get_content_type(method)
|
30
|
+
o = __options[method]
|
31
|
+
o.is_a?(Hash) ? o[:content_type] : nil
|
117
32
|
end
|
118
33
|
|
119
|
-
|
120
|
-
|
121
|
-
|
34
|
+
def self.get_render(method)
|
35
|
+
o = __options[method]
|
36
|
+
o.is_a?(Hash) ? o[:render] : nil
|
122
37
|
end
|
123
38
|
end
|
124
39
|
end
|
data/lib/alfa/database.rb
CHANGED
data/lib/alfa/exceptions.rb
CHANGED
@@ -3,6 +3,8 @@ module Alfa
|
|
3
3
|
# Route not found
|
4
4
|
class Route404 < StandardError; end
|
5
5
|
|
6
|
+
class Route403 < StandardError; end
|
7
|
+
|
6
8
|
class HttpRedirect < StandardError
|
7
9
|
attr_reader :url, :code
|
8
10
|
def initialize(url, code)
|
@@ -10,6 +12,9 @@ module Alfa
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
15
|
+
|
16
|
+
class NoSuchController < StandardError; end
|
17
|
+
|
13
18
|
# Application's config.project_root required
|
14
19
|
class E001 < StandardError; end
|
15
20
|
|
data/lib/alfa/logger.rb
CHANGED
@@ -5,7 +5,7 @@ require 'alfa/support'
|
|
5
5
|
module Alfa
|
6
6
|
class NullLogger
|
7
7
|
def portion(*args, &block)
|
8
|
-
l =
|
8
|
+
l = self.class.new
|
9
9
|
yield(l)
|
10
10
|
end
|
11
11
|
|
@@ -22,8 +22,8 @@ module Alfa
|
|
22
22
|
|
23
23
|
class Logger < ::Logger
|
24
24
|
|
25
|
-
def initialize(logdev
|
26
|
-
super
|
25
|
+
def initialize(logdev)
|
26
|
+
super(nil)
|
27
27
|
@logdev = logdev
|
28
28
|
@formatter = Formatter.new
|
29
29
|
end
|
@@ -32,6 +32,7 @@ module Alfa
|
|
32
32
|
io = VirtualIO.new
|
33
33
|
l = Logger.new(io)
|
34
34
|
l.formatter = @formatter
|
35
|
+
l.level = @level
|
35
36
|
yield(l)
|
36
37
|
self << io.join
|
37
38
|
flush if kwargs[:sync]
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Alfa
|
2
|
+
class Resourcer
|
3
|
+
def initialize
|
4
|
+
@resources = {
|
5
|
+
action: {styles: [], scripts:[], added_scripts: []},
|
6
|
+
layout: {styles: [], scripts:[], added_scripts: []},
|
7
|
+
snippet: {styles: [], scripts:[], added_scripts: []},
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](name)
|
12
|
+
@resources[@cursor][name]
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param l Symbol
|
16
|
+
def level=(l)
|
17
|
+
raise "level should be on of #{@resources.keys}" unless @resources.keys.include?(l)
|
18
|
+
@cursor = l
|
19
|
+
end
|
20
|
+
|
21
|
+
def styles
|
22
|
+
@resources[:layout][:styles].concat(@resources[:action][:styles]).concat(@resources[:snippet][:styles])
|
23
|
+
end
|
24
|
+
|
25
|
+
def scripts
|
26
|
+
@resources[:layout][:scripts].concat(@resources[:action][:scripts]).concat(@resources[:snippet][:scripts])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/alfa/router.rb
CHANGED
@@ -6,6 +6,8 @@ module Alfa
|
|
6
6
|
|
7
7
|
class << self
|
8
8
|
attr_accessor :apps_dir
|
9
|
+
attr_reader :apps
|
10
|
+
attr_reader :mounts
|
9
11
|
end
|
10
12
|
|
11
13
|
# initialize class variables
|
@@ -36,6 +38,9 @@ module Alfa
|
|
36
38
|
|
37
39
|
def self.reset
|
38
40
|
@routes.clear
|
41
|
+
@cursor = @routes
|
42
|
+
@cursors_stack = []
|
43
|
+
@mounts.clear
|
39
44
|
@apps_dir = nil
|
40
45
|
end
|
41
46
|
|
@@ -70,6 +75,7 @@ module Alfa
|
|
70
75
|
path, a = path.first.to_a
|
71
76
|
app = a.to_sym
|
72
77
|
end
|
78
|
+
path = "#{path}/" unless path[-1] == '/'
|
73
79
|
@mounts << {:path => path, :app => app, :options => options}
|
74
80
|
if @apps_dir
|
75
81
|
self.context :app => app do
|
@@ -122,9 +128,19 @@ module Alfa
|
|
122
128
|
fail_flag = false
|
123
129
|
rule_segments.zip(url_segments).each do |rule_segment, url_segment|
|
124
130
|
skip_flag = true if rule_segment == '**'
|
125
|
-
if rule_segment =~
|
126
|
-
|
127
|
-
|
131
|
+
if rule_segment =~ /\A:[a-z]+\w*\z/i && url_segment =~ /\A[a-z0-9_]+\z/
|
132
|
+
key = rule_segment[1..-1].to_sym
|
133
|
+
url_segment = url_segment.to_sym if [:controller, :action].include?(key)
|
134
|
+
pares[key] = url_segment
|
135
|
+
elsif rule_segment.to_s[-1..-1] == '?'
|
136
|
+
key = rule_segment[1..-2].to_sym
|
137
|
+
if [:action].include?(key)
|
138
|
+
url_segment = url_segment.nil? ? :index : url_segment.to_sym
|
139
|
+
else
|
140
|
+
url_segment = nil
|
141
|
+
end
|
142
|
+
pares[key] = url_segment
|
143
|
+
elsif (rule_segment == url_segment) || (rule_segment == '*' && url_segment =~ /\A[a-z0-9_]+\z/) || (rule_segment == nil && skip_flag) || rule_segment == '**'
|
128
144
|
else
|
129
145
|
fail_flag = true
|
130
146
|
break
|
@@ -147,15 +163,17 @@ module Alfa
|
|
147
163
|
# @return route, params
|
148
164
|
# route is route that given in routes.rb
|
149
165
|
# params is detected params
|
150
|
-
def self.find_route
|
166
|
+
def self.find_route(url, exclude: [])
|
151
167
|
@routes.each do |route|
|
152
168
|
if route[:context].is_a? Hash # container
|
153
169
|
if self.app_match?(route[:context][:app][:path], url)
|
154
170
|
url = url[(route[:context][:app][:path].length-1)..-1]
|
155
171
|
route[:routes].each do |r|
|
156
|
-
|
157
|
-
|
158
|
-
|
172
|
+
unless exclude.include?(r[:rule])
|
173
|
+
is_success, params = self.route_match?(r[:rule], url)
|
174
|
+
r[:options][:app] = route[:context][:app][:app]
|
175
|
+
return r, params if is_success
|
176
|
+
end
|
159
177
|
end
|
160
178
|
raise Alfa::Exceptions::Route404
|
161
179
|
end
|
@@ -176,13 +194,15 @@ module Alfa
|
|
176
194
|
if route[:context].is_a?(Hash) # container
|
177
195
|
if route[:context][:app][:app] == kwargs[:app]
|
178
196
|
route[:routes].each do |r|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
197
|
+
unless r[:rule].is_a?(Fixnum)
|
198
|
+
r[:placeholders] = r[:rule].scan(/:([a-z_][a-z0-9_]*)/).map{|m| m[0].to_sym}.sort unless r[:placeholders]
|
199
|
+
if (r[:placeholders] - kwargs.keys).empty? &&
|
200
|
+
(kwargs.keys & r[:options].keys).all?{|key| kwargs[key] == r[:options][key]} &&
|
201
|
+
(kwargs.keys - [:app] - r[:placeholders] - r[:options].keys).empty?
|
202
|
+
result = File.join(route[:context][:app][:path], r[:rule].strtr(kwargs.map{|key, value| [":#{key}", value.to_s]}))
|
203
|
+
result += "?#{::Rack::Utils.build_query(params)}" if params.any?
|
204
|
+
return result
|
205
|
+
end
|
186
206
|
end
|
187
207
|
end
|
188
208
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Alfa
|
2
|
+
class Snippeter
|
3
|
+
@snippets = {}
|
4
|
+
@config = {}
|
5
|
+
@cursor = nil
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :config
|
9
|
+
attr_writer :mounts
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param Symbol app
|
13
|
+
def self.load
|
14
|
+
@mounts.each do |m|
|
15
|
+
app = m[:app]
|
16
|
+
path = File.join(@config[:project_root], 'apps', app.to_s, 'snippets.rb')
|
17
|
+
@cursor = app
|
18
|
+
@snippets[@cursor] ||= {}
|
19
|
+
if File.exist?(path)
|
20
|
+
load_in_instance_context path
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param Symbol name
|
26
|
+
# @param Proc &block
|
27
|
+
def self.snippet(name, &block)
|
28
|
+
raise 'Snippet name should be a Symbol' unless name.is_a?(Symbol)
|
29
|
+
raise 'Snippets requires scope' unless @cursor
|
30
|
+
@snippets[@cursor][name] = block
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def self.[](name)
|
35
|
+
if @config[:run_mode] == :development
|
36
|
+
@snippets.clear
|
37
|
+
self.load
|
38
|
+
end
|
39
|
+
@snippets[name]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|