rad_kit 0.0.8 → 0.0.9
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.
- 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
|