alfa 0.0.5.pre → 0.0.6.pre
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.
- 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
|