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.
Files changed (84) hide show
  1. data/lib/components/captcha.rb +4 -4
  2. data/lib/components/kit.rb +5 -5
  3. data/lib/components/kit.yml +0 -2
  4. data/lib/components/models.rb +2 -5
  5. data/lib/components/models.yml +3 -0
  6. data/lib/kit/controller/authorized.rb +9 -8
  7. data/lib/kit/controller/captcha.rb +6 -6
  8. data/lib/kit/controller/localized.rb +2 -2
  9. data/lib/kit/gems.rb +12 -8
  10. data/lib/kit/i18n.rb +3 -3
  11. data/lib/kit/i18n/locales/ru/pluralization.rb +3 -3
  12. data/lib/kit/kit.rb +7 -7
  13. data/lib/kit/kit_text_utils.rb +6 -6
  14. data/lib/kit/misc/prepare_model.rb +4 -4
  15. data/lib/kit/models.rb +22 -5
  16. data/lib/kit/models/attachment_file.rb +27 -0
  17. data/lib/kit/models/{attachments_uploader_helper.rb → attachments_helper.rb} +34 -28
  18. data/lib/kit/models/authorized.rb +64 -63
  19. data/lib/kit/models/authorized_object.rb +70 -73
  20. data/lib/kit/models/base_file.rb +37 -0
  21. data/lib/kit/models/config.rb +30 -0
  22. data/lib/kit/models/indexes.rb +30 -0
  23. data/lib/kit/models/miscellaneous.rb +7 -1
  24. data/lib/kit/models/role.rb +17 -17
  25. data/lib/kit/models/tags.rb +71 -0
  26. data/lib/kit/models/tags_mixin.rb +39 -0
  27. data/lib/kit/mongodb_model.rb +13 -0
  28. data/lib/kit/mongodb_model/text_processor.rb +32 -0
  29. data/lib/kit/spec.rb +30 -30
  30. data/lib/kit/spec/items_controller_crud.rb +9 -9
  31. data/lib/kit/support.rb +1 -1
  32. data/lib/kit/tasks.rb +3 -7
  33. data/lib/text_utils.rb +2 -2
  34. data/lib/text_utils/code_highlighter.rb +17 -17
  35. data/lib/text_utils/custom_markdown.rb +7 -7
  36. data/lib/text_utils/ensure_utf.rb +3 -3
  37. data/lib/text_utils/format_qualifier.rb +2 -2
  38. data/lib/text_utils/html_sanitizer.rb +9 -9
  39. data/lib/text_utils/markdown.rb +9 -9
  40. data/lib/text_utils/pipe.rb +1 -1
  41. data/lib/text_utils/processor.rb +3 -3
  42. data/lib/text_utils/support.rb +3 -3
  43. data/lib/text_utils/truncate.rb +4 -4
  44. data/readme.md +3 -1
  45. data/spec/controller/authorization_spec.rb +45 -45
  46. data/spec/controller/captcha_spec.rb +18 -18
  47. data/spec/controller/comments_spec.rb +16 -14
  48. data/spec/controller/items_spec.rb +16 -17
  49. data/spec/i18n/i18n_spec.rb +5 -5
  50. data/spec/misc/kit_text_utils_spec.rb +5 -5
  51. data/spec/misc/prepare_model_spec.rb +6 -6
  52. data/spec/misc/user_error_spec.rb +8 -8
  53. data/spec/models/{attachments_uploader_helper_spec.rb → attachments_helper_spec.rb} +46 -50
  54. data/spec/models/{attachments_uploader_helper_spec → attachments_helper_spec}/v1/a.txt +0 -0
  55. data/spec/models/{attachments_uploader_helper_spec → attachments_helper_spec}/v1/b.txt +0 -0
  56. data/spec/models/{attachments_uploader_helper_spec → attachments_helper_spec}/v2/a.txt +0 -0
  57. data/spec/models/attachments_spec.rb +4 -7
  58. data/spec/models/authorization_spec.rb +15 -15
  59. data/spec/models/authorized_object_spec.rb +75 -75
  60. data/spec/models/item_spec.rb +44 -40
  61. data/spec/models/role_spec.rb +4 -4
  62. data/spec/models/tags_spec.rb +47 -21
  63. data/spec/models/uploader_spec.rb +13 -23
  64. data/spec/mongodb_model/text_processor_spec.rb +26 -0
  65. data/spec/spec_helper.rb +6 -4
  66. data/spec/spec_helper/factories.rb +3 -3
  67. data/spec/spec_helper/user.rb +4 -7
  68. data/spec/text_utils/code_highlighter_spec.rb +7 -7
  69. data/spec/text_utils/custom_markdown_spec.rb +14 -14
  70. data/spec/text_utils/format_qualifier_spec.rb +6 -6
  71. data/spec/text_utils/html_sanitizer_spec.rb +15 -15
  72. data/spec/text_utils/markdown_spec.rb +17 -17
  73. data/spec/text_utils/pipe_spec.rb +5 -5
  74. data/spec/text_utils/spec_helper.rb +1 -1
  75. data/spec/text_utils/text_processor_shared.rb +1 -1
  76. data/spec/text_utils/truncate_spec.rb +5 -5
  77. metadata +118 -114
  78. data/lib/kit/models/attachment_uploader.rb +0 -15
  79. data/lib/kit/models/file_uploader.rb +0 -26
  80. data/lib/kit/models_after.rb +0 -27
  81. data/lib/kit/mongoid.rb +0 -22
  82. data/lib/kit/mongoid/rad_miscellaneous.rb +0 -36
  83. data/lib/kit/mongoid/text_processor.rb +0 -44
  84. 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
@@ -1 +1,7 @@
1
- STRONG_NAME = /\A[a-z_][a-z_0-9]*\Z/
1
+ module Models::Miscellaneous
2
+ delegate :t, to: I18n
3
+
4
+ module ClassMethods
5
+ delegate :t, to: I18n
6
+ end
7
+ end
@@ -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,13 @@
1
+ require 'mongo/model'
2
+ require 'file_model'
3
+ require 'rad'
4
+
5
+
6
+ module Models; end
7
+
8
+ %w(
9
+ text_processor
10
+ ).each{|n| require "kit/mongodb_model/#{n}"}
11
+
12
+ Mongo::Model.inherit Mongo::Model::TextProcessor
13
+ rad.extension :mm_extensions
@@ -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 'mongoid_misc'
5
- require 'mongoid_misc/spec'
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
- def with_files
43
- before do
44
- rad.config.fs_path = CarrierWaveExtSpecHelper::TEST_PATH
45
- rad.config.fs_cache_path = CarrierWaveExtSpecHelper::TEST_CACHE_PATH
46
-
47
- Models::FileUploader.storage :file
48
- end
49
-
50
- super
51
- end
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
- with_mongoid
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