rad_kit 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/components/captcha.rb +4 -4
- data/lib/components/kit.rb +5 -5
- data/lib/components/kit.yml +0 -2
- data/lib/components/models.rb +2 -5
- data/lib/components/models.yml +3 -0
- data/lib/kit/controller/authorized.rb +9 -8
- data/lib/kit/controller/captcha.rb +6 -6
- data/lib/kit/controller/localized.rb +2 -2
- data/lib/kit/gems.rb +12 -8
- data/lib/kit/i18n.rb +3 -3
- data/lib/kit/i18n/locales/ru/pluralization.rb +3 -3
- data/lib/kit/kit.rb +7 -7
- data/lib/kit/kit_text_utils.rb +6 -6
- data/lib/kit/misc/prepare_model.rb +4 -4
- data/lib/kit/models.rb +22 -5
- data/lib/kit/models/attachment_file.rb +27 -0
- data/lib/kit/models/{attachments_uploader_helper.rb → attachments_helper.rb} +34 -28
- data/lib/kit/models/authorized.rb +64 -63
- data/lib/kit/models/authorized_object.rb +70 -73
- data/lib/kit/models/base_file.rb +37 -0
- data/lib/kit/models/config.rb +30 -0
- data/lib/kit/models/indexes.rb +30 -0
- data/lib/kit/models/miscellaneous.rb +7 -1
- data/lib/kit/models/role.rb +17 -17
- data/lib/kit/models/tags.rb +71 -0
- data/lib/kit/models/tags_mixin.rb +39 -0
- data/lib/kit/mongodb_model.rb +13 -0
- data/lib/kit/mongodb_model/text_processor.rb +32 -0
- data/lib/kit/spec.rb +30 -30
- data/lib/kit/spec/items_controller_crud.rb +9 -9
- data/lib/kit/support.rb +1 -1
- data/lib/kit/tasks.rb +3 -7
- data/lib/text_utils.rb +2 -2
- data/lib/text_utils/code_highlighter.rb +17 -17
- data/lib/text_utils/custom_markdown.rb +7 -7
- data/lib/text_utils/ensure_utf.rb +3 -3
- data/lib/text_utils/format_qualifier.rb +2 -2
- data/lib/text_utils/html_sanitizer.rb +9 -9
- data/lib/text_utils/markdown.rb +9 -9
- data/lib/text_utils/pipe.rb +1 -1
- data/lib/text_utils/processor.rb +3 -3
- data/lib/text_utils/support.rb +3 -3
- data/lib/text_utils/truncate.rb +4 -4
- data/readme.md +3 -1
- data/spec/controller/authorization_spec.rb +45 -45
- data/spec/controller/captcha_spec.rb +18 -18
- data/spec/controller/comments_spec.rb +16 -14
- data/spec/controller/items_spec.rb +16 -17
- data/spec/i18n/i18n_spec.rb +5 -5
- data/spec/misc/kit_text_utils_spec.rb +5 -5
- data/spec/misc/prepare_model_spec.rb +6 -6
- data/spec/misc/user_error_spec.rb +8 -8
- data/spec/models/{attachments_uploader_helper_spec.rb → attachments_helper_spec.rb} +46 -50
- data/spec/models/{attachments_uploader_helper_spec → attachments_helper_spec}/v1/a.txt +0 -0
- data/spec/models/{attachments_uploader_helper_spec → attachments_helper_spec}/v1/b.txt +0 -0
- data/spec/models/{attachments_uploader_helper_spec → attachments_helper_spec}/v2/a.txt +0 -0
- data/spec/models/attachments_spec.rb +4 -7
- data/spec/models/authorization_spec.rb +15 -15
- data/spec/models/authorized_object_spec.rb +75 -75
- data/spec/models/item_spec.rb +44 -40
- data/spec/models/role_spec.rb +4 -4
- data/spec/models/tags_spec.rb +47 -21
- data/spec/models/uploader_spec.rb +13 -23
- data/spec/mongodb_model/text_processor_spec.rb +26 -0
- data/spec/spec_helper.rb +6 -4
- data/spec/spec_helper/factories.rb +3 -3
- data/spec/spec_helper/user.rb +4 -7
- data/spec/text_utils/code_highlighter_spec.rb +7 -7
- data/spec/text_utils/custom_markdown_spec.rb +14 -14
- data/spec/text_utils/format_qualifier_spec.rb +6 -6
- data/spec/text_utils/html_sanitizer_spec.rb +15 -15
- data/spec/text_utils/markdown_spec.rb +17 -17
- data/spec/text_utils/pipe_spec.rb +5 -5
- data/spec/text_utils/spec_helper.rb +1 -1
- data/spec/text_utils/text_processor_shared.rb +1 -1
- data/spec/text_utils/truncate_spec.rb +5 -5
- metadata +118 -114
- data/lib/kit/models/attachment_uploader.rb +0 -15
- data/lib/kit/models/file_uploader.rb +0 -26
- data/lib/kit/models_after.rb +0 -27
- data/lib/kit/mongoid.rb +0 -22
- data/lib/kit/mongoid/rad_miscellaneous.rb +0 -36
- data/lib/kit/mongoid/text_processor.rb +0 -44
- data/spec/mongoid/basic_spec.rb +0 -36
@@ -0,0 +1,37 @@
|
|
1
|
+
class Models::BaseFile
|
2
|
+
inherit FileModel
|
3
|
+
|
4
|
+
# box :default
|
5
|
+
# storage rad.config.fs_type
|
6
|
+
|
7
|
+
# def sanitize_regexp
|
8
|
+
# /[^[:word:]\.\-\+\s_]/i
|
9
|
+
# end
|
10
|
+
|
11
|
+
def model_id
|
12
|
+
model._id || model._parent._id || raise("id not defined!")
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_path name, version = nil
|
16
|
+
"#{rad.models.fs['prefix']}/system/#{model.class.alias.underscore}/#{model_id}" + build_standard_path(name, version)
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_url name, version = nil
|
20
|
+
"#{rad.models.fs['host']}#{rad.models.fs['prefix']}/system/#{model.class.alias.underscore}/#{model_id}" + build_standard_url(name, version)
|
21
|
+
end
|
22
|
+
|
23
|
+
# def file_path
|
24
|
+
# "#{rad.config.fs_prefix}/system/#{model.class.model_name.underscore}/#{model.id}"
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# def store_dir
|
28
|
+
# "#{root}#{file_path}"
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# def extension_white_list
|
32
|
+
# [/.*/]
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def cache_dir; rad.config.fs_cache_path end
|
36
|
+
# def root; rad.config.fs_path end
|
37
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Mongo.metaclass_eval do
|
2
|
+
def db name
|
3
|
+
config = rad.models.db[name.to_s] || raise("no database config for #{name} alias!")
|
4
|
+
host, port, options = config['host'], config['port'], (config['options'] || {})
|
5
|
+
connection = self.connection host, port, options
|
6
|
+
db_name = config['name'] || raise("no database name for #{name} alias!")
|
7
|
+
connection.db db_name
|
8
|
+
end
|
9
|
+
cache_method_with_params :db
|
10
|
+
|
11
|
+
def connection host, port, options
|
12
|
+
options[:logger] = rad.logger unless options.include? :logger
|
13
|
+
Mongo::Connection.new host, port, options
|
14
|
+
end
|
15
|
+
cache_method_with_params :connection
|
16
|
+
end
|
17
|
+
|
18
|
+
FileModel.metaclass_eval do
|
19
|
+
def box name
|
20
|
+
raise 'invalid box name' unless name == :default
|
21
|
+
|
22
|
+
config = rad.models.fs
|
23
|
+
driver_class = config['driver_class'] || raise("driver for FileModel not defined!")
|
24
|
+
_class = eval driver_class, TOPLEVEL_BINDING, __FILE__, __LINE__
|
25
|
+
options = config['options'] || {}
|
26
|
+
driver = _class.new options
|
27
|
+
Vos::Box.new driver
|
28
|
+
end
|
29
|
+
cache_method_with_params :box
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Kit
|
2
|
+
|
3
|
+
add space_id prefix to all indexes
|
4
|
+
|
5
|
+
Models::Item.collection.instance_eval do
|
6
|
+
create_index [[:_class, 1]]
|
7
|
+
create_index [[:name, 1]], unique: true
|
8
|
+
create_index [[:owner_name, 1]]
|
9
|
+
create_index [[:slug, 1]], unique: true
|
10
|
+
create_index [[:state, 1]]
|
11
|
+
create_index [[:tags, 1]]
|
12
|
+
create_index [[:created_at, 1]]
|
13
|
+
create_index [[:updated_at, 1]]
|
14
|
+
create_index [[:viewers, 1]]
|
15
|
+
end
|
16
|
+
|
17
|
+
Models::Comment.collection.instance_eval do
|
18
|
+
create_index [[:item_id, 1]]
|
19
|
+
end
|
20
|
+
|
21
|
+
Models::SecureToken.collection.instance_eval do
|
22
|
+
create_index [[:token, 1]], unique: true
|
23
|
+
create_index [[:expires_at, 1]]
|
24
|
+
create_index [[:user_id, 1]]
|
25
|
+
end
|
26
|
+
|
27
|
+
Models::Tag.collection.instance_eval do
|
28
|
+
create_index [[:name, 1]], unique: true
|
29
|
+
create_index [[:count, 1]]
|
30
|
+
end
|
data/lib/kit/models/role.rb
CHANGED
@@ -4,47 +4,47 @@ class Role
|
|
4
4
|
PRESERVED_USER_NAMES = SYSTEM_ROLES
|
5
5
|
|
6
6
|
class << self
|
7
|
-
|
8
|
-
def normalize_roles roles
|
7
|
+
|
8
|
+
def normalize_roles roles
|
9
9
|
ordinary_roles, ordered_roles = split roles
|
10
|
-
ordinary_roles << lower_role(ordered_roles)
|
10
|
+
ordinary_roles << lower_role(ordered_roles)
|
11
11
|
ordinary_roles.sort
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def denormalize_to_higher_roles roles
|
15
15
|
ordinary_roles, ordered_roles = split roles
|
16
16
|
ordinary_roles.push *higher_roles(lower_role(ordered_roles))
|
17
17
|
ordinary_roles.sort
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def denormalize_to_lower_roles roles
|
21
21
|
ordinary_roles, ordered_roles = split roles
|
22
22
|
ordinary_roles.push *lower_roles(higher_role(ordered_roles))
|
23
23
|
ordinary_roles.sort
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def higher_role roles
|
27
27
|
ORDERED_ROLES.each do |role|
|
28
28
|
return role if roles.include? role
|
29
29
|
end
|
30
30
|
nil
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def lower_role roles
|
34
34
|
ORDERED_ROLES.reverse.each do |role|
|
35
35
|
return role if roles.include? role
|
36
36
|
end
|
37
37
|
nil
|
38
38
|
end
|
39
|
-
|
40
|
-
def major_roles roles
|
39
|
+
|
40
|
+
def major_roles roles
|
41
41
|
major_roles = roles.select{|role| !SYSTEM_ROLES.include?(role)}
|
42
42
|
if higher_role = higher_role(roles)
|
43
43
|
major_roles << higher_role
|
44
44
|
end
|
45
45
|
major_roles.sort
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def minor_roles roles
|
49
49
|
minor_roles = roles.select{|role| !SYSTEM_ROLES.include?(role)}
|
50
50
|
if lower_role = lower_role(roles)
|
@@ -52,26 +52,26 @@ class Role
|
|
52
52
|
end
|
53
53
|
minor_roles.sort
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
protected
|
57
57
|
def split roles
|
58
58
|
ordinary_roles = []
|
59
59
|
ordered_roles = []
|
60
60
|
|
61
|
-
roles.collect do |role|
|
61
|
+
roles.collect do |role|
|
62
62
|
if ORDERED_ROLES.include? role
|
63
63
|
ordered_roles << role
|
64
64
|
else
|
65
65
|
ordinary_roles << role
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
[ordinary_roles, ordered_roles]
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def lower_roles role
|
73
73
|
return [] if role.nil?
|
74
|
-
|
74
|
+
|
75
75
|
role.must_be.in ORDERED_ROLES
|
76
76
|
index = ORDERED_ROLES.index role
|
77
77
|
ORDERED_ROLES[index..-1]
|
@@ -79,10 +79,10 @@ class Role
|
|
79
79
|
|
80
80
|
def higher_roles role
|
81
81
|
return [] if role.nil?
|
82
|
-
|
82
|
+
|
83
83
|
role.must_be.in ORDERED_ROLES
|
84
84
|
index = ORDERED_ROLES.index role
|
85
85
|
ORDERED_ROLES[0..index]
|
86
|
-
end
|
86
|
+
end
|
87
87
|
end
|
88
88
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class Models::Tags < Array
|
2
|
+
inherit Mongo::Model
|
3
|
+
|
4
|
+
def initialize array = nil
|
5
|
+
super()
|
6
|
+
replace array if array
|
7
|
+
end
|
8
|
+
|
9
|
+
#
|
10
|
+
# Working with context
|
11
|
+
#
|
12
|
+
class ContextTags < Array
|
13
|
+
def as_string; join(", ") end
|
14
|
+
end
|
15
|
+
|
16
|
+
def topic
|
17
|
+
get_tags{|tag| tag !~ /:/}
|
18
|
+
end
|
19
|
+
def topic= value
|
20
|
+
set_tags(value){|tag| tag !~ /:/}
|
21
|
+
end
|
22
|
+
|
23
|
+
def as_string; join(", ") end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Updating Tag and counts cache
|
27
|
+
#
|
28
|
+
attr_accessor :_changes
|
29
|
+
before_save do |tags|
|
30
|
+
original_tags = (tags._parent && tags._parent.original.try(:tags)) || Models::Tags.new
|
31
|
+
tags._changes = [original_tags, tags] if tags != original_tags
|
32
|
+
end
|
33
|
+
after_save {|tags| Models::Tag.update_tags! *tags._changes if tags._changes}
|
34
|
+
after_destroy{|tags| Models::Tag.delete_tags! tags unless tags.empty?}
|
35
|
+
|
36
|
+
protected
|
37
|
+
def validate_tag_names
|
38
|
+
errors.add :base, t(:invalid_tags) unless all?{|tag| Models::Tag.valid_name?(tag)}
|
39
|
+
end
|
40
|
+
validate :validate_tag_names
|
41
|
+
|
42
|
+
def method_missing m, *args, &b
|
43
|
+
if m !~ /=$/
|
44
|
+
context = m.to_s
|
45
|
+
args.size.must == 0
|
46
|
+
get_tags{|tag| tag =~ /#{context}:/}
|
47
|
+
else
|
48
|
+
context = m.to_s[0..-2]
|
49
|
+
args.size.must == 1
|
50
|
+
value = args.first
|
51
|
+
set_tags(value){|tag| tag =~ /#{context}:/}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_tags value, &selector
|
56
|
+
new_tags = if value.is_a? String
|
57
|
+
value.split(Models::Tag::TAG_LIST_DELIMITER).collect{|name| name.strip}.sort
|
58
|
+
else
|
59
|
+
value.must_be.a Array
|
60
|
+
end
|
61
|
+
new_tags.select!(&selector)
|
62
|
+
|
63
|
+
reject!(&selector)
|
64
|
+
new_tags.each{|tag| push tag}
|
65
|
+
sort!
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_tags &selector
|
69
|
+
ContextTags.new select(&selector)
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Models::TagsMixin
|
2
|
+
def tags; @tags ||= Models::Tags.new end
|
3
|
+
def tags= tags; @tags = Models::Tags.new tags end
|
4
|
+
|
5
|
+
def topics_as_string= value
|
6
|
+
tags.topic = value
|
7
|
+
end
|
8
|
+
def topics_as_string
|
9
|
+
tags.topic.as_string
|
10
|
+
end
|
11
|
+
|
12
|
+
inherited do
|
13
|
+
before_validate :add_class_to_tags
|
14
|
+
validate :validate_class_in_tags
|
15
|
+
after_validate :copy_errors_from_tags
|
16
|
+
after_build :build_tags
|
17
|
+
|
18
|
+
assign :topics_as_string, String, true
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def add_class_to_tags
|
23
|
+
cname = "_class:#{self.class.name}"
|
24
|
+
tags.push(cname).sort! unless tags.include? cname
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_class_in_tags
|
28
|
+
cname = "_class:#{self.class.name}"
|
29
|
+
errors.add :base, "no class in tags!" unless tags.include? cname
|
30
|
+
end
|
31
|
+
|
32
|
+
def copy_errors_from_tags
|
33
|
+
errors[:base] = tags.errors[:base] unless tags.errors.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_tags
|
37
|
+
self.tags = tags
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mongo::Model::TextProcessor
|
2
|
+
module ClassMethods
|
3
|
+
def available_as_markup attr_name
|
4
|
+
original_attr_name = :"original_#{attr_name}"
|
5
|
+
|
6
|
+
raise "attribute #{attr_name} not defined!" unless method_defined? attr_name
|
7
|
+
attr_reader original_attr_name unless method_defined? original_attr_name
|
8
|
+
|
9
|
+
iv_name, original_iv_name = :"@#{attr_name}", :"@#{original_attr_name}"
|
10
|
+
|
11
|
+
define_method :"#{attr_name}=" do |value|
|
12
|
+
instance_variable_set iv_name, value
|
13
|
+
instance_variable_set original_iv_name, value
|
14
|
+
end
|
15
|
+
|
16
|
+
define_method "#{original_attr_name}=" do |value|
|
17
|
+
instance_variable_set iv_name, TextUtils.markup(value)
|
18
|
+
instance_variable_set original_iv_name, value
|
19
|
+
end
|
20
|
+
|
21
|
+
define_method "#{attr_name}_as_text" do
|
22
|
+
value = instance_variable_get iv_name
|
23
|
+
return "" if value.blank?
|
24
|
+
Nokogiri::XML(value).content
|
25
|
+
end
|
26
|
+
|
27
|
+
after_validate do |model|
|
28
|
+
model.errors.add original_attr_name, model.errors[attr_name] if model.errors.include?(attr_name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/kit/spec.rb
CHANGED
@@ -1,31 +1,30 @@
|
|
1
1
|
require 'rad'
|
2
2
|
require 'rad/spec'
|
3
3
|
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
require 'carrierwave_ext/spec'
|
4
|
+
require 'mongo/model'
|
5
|
+
require 'mongo/model/spec'
|
7
6
|
|
8
7
|
|
9
|
-
#
|
8
|
+
#
|
10
9
|
# SaaS
|
11
10
|
#
|
12
11
|
unless ENV['saas'] == 'false'
|
13
12
|
begin
|
14
|
-
require 'saas/spec'
|
13
|
+
require 'saas/spec'
|
15
14
|
rescue LoadError
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
18
|
|
20
|
-
#
|
19
|
+
#
|
21
20
|
# User
|
22
|
-
#
|
21
|
+
#
|
23
22
|
rad.register :user
|
24
23
|
rspec do
|
25
24
|
def login_as user
|
26
25
|
rad.user = user
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
def self.login_as name, options = {}
|
30
29
|
before do
|
31
30
|
@user = Factory.create name, options
|
@@ -35,38 +34,39 @@ rspec do
|
|
35
34
|
end
|
36
35
|
|
37
36
|
|
38
|
-
#
|
37
|
+
#
|
39
38
|
# CarrierWave
|
40
|
-
#
|
41
|
-
module Rad::CarrierWaveSpecHelper
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
rspec.extend Rad::CarrierWaveSpecHelper
|
39
|
+
#
|
40
|
+
# module Rad::CarrierWaveSpecHelper
|
41
|
+
# def with_files
|
42
|
+
# before do
|
43
|
+
# rad.config.fs_path = CarrierWaveExtSpecHelper::TEST_PATH
|
44
|
+
# rad.config.fs_cache_path = CarrierWaveExtSpecHelper::TEST_CACHE_PATH
|
45
|
+
#
|
46
|
+
# Models::BaseFile.storage :file
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# super
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# rspec.extend Rad::CarrierWaveSpecHelper
|
54
53
|
|
55
54
|
|
56
|
-
#
|
55
|
+
#
|
57
56
|
# Miscellaneous
|
58
|
-
#
|
57
|
+
#
|
59
58
|
rspec do
|
60
59
|
alias_method :call, :wcall
|
61
|
-
alias_method :pcall, :post_wcall
|
60
|
+
alias_method :pcall, :post_wcall
|
62
61
|
alias_method :set_call, :set_wcall
|
63
|
-
|
64
|
-
class << self
|
62
|
+
|
63
|
+
class << self
|
65
64
|
def with_models
|
66
|
-
|
65
|
+
with_mongo_model
|
66
|
+
with_file_model
|
67
67
|
rad.extension :with_models, self
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
def with_controllers
|
71
71
|
with_models
|
72
72
|
end
|