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.
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