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
@@ -4,15 +4,15 @@ shared_examples_for "Items Controller CRUD" do
|
|
4
4
|
@model_class ||= @controller_class.model_class
|
5
5
|
@model_name ||= @model_class.alias.underscore
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
%w{html json}.each do |format|
|
9
9
|
it "show :#{format}" do
|
10
|
-
@item = Factory.create @model_name
|
10
|
+
@item = Factory.create @model_name
|
11
11
|
call :show, id: @item.to_param, format: format
|
12
12
|
response.should be_ok
|
13
13
|
response.body.should include(@item.name)
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "all :#{format}" do
|
17
17
|
@item = Factory.create @model_name
|
18
18
|
call :all, format: format
|
@@ -20,19 +20,19 @@ shared_examples_for "Items Controller CRUD" do
|
|
20
20
|
response.body.should include(@item.name)
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "edit :js" do
|
25
25
|
item = Factory.create @model_name
|
26
26
|
call :edit, id: item.to_param, format: 'js'
|
27
27
|
response.should be_ok
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
%w{js json}.each do |format|
|
31
|
-
it "new :#{format}" do
|
31
|
+
it "new :#{format}" do
|
32
32
|
call :new, format: format
|
33
33
|
response.should be_ok
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
it "create :#{format}" do
|
37
37
|
item_attributes = Factory.attributes_for @model_name
|
38
38
|
pcall :create, model: item_attributes, format: format
|
@@ -42,7 +42,7 @@ shared_examples_for "Items Controller CRUD" do
|
|
42
42
|
item = @model_class.first
|
43
43
|
item.name.should == item_attributes[:name]
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it "update :#{format}" do
|
47
47
|
item = Factory.create @model_name
|
48
48
|
pcall :update, id: item.to_param, model: {name: 'new_name'}, format: format
|
@@ -60,5 +60,5 @@ shared_examples_for "Items Controller CRUD" do
|
|
60
60
|
response.should be_ok
|
61
61
|
@model_class.count.should == 0
|
62
62
|
end
|
63
|
-
end
|
63
|
+
end
|
64
64
|
end
|
data/lib/kit/support.rb
CHANGED
data/lib/kit/tasks.rb
CHANGED
@@ -2,17 +2,13 @@ require 'rake_ext'
|
|
2
2
|
|
3
3
|
require 'rad/tasks'
|
4
4
|
require 'rad/assets/tasks'
|
5
|
-
require '
|
5
|
+
require 'mongo/migration/tasks'
|
6
6
|
|
7
7
|
namespace :db do
|
8
8
|
desc "Internal task to prepare migration environment"
|
9
9
|
task migration_evnironment: :environment do
|
10
|
-
require '
|
11
|
-
|
12
|
-
|
13
|
-
adapter = Mongo::Migration::Mongoid.new
|
14
|
-
Mongo.migration = Mongo::Migration.new adapter
|
15
|
-
|
10
|
+
require 'mongo/migration'
|
11
|
+
|
16
12
|
Dir["#{rad.runtime_path}/db/**/*.rb"].each{|f| require f.sub(/\.rb$/, '')}
|
17
13
|
end
|
18
14
|
end
|
data/lib/text_utils.rb
CHANGED
@@ -2,7 +2,7 @@ require 'digest/md5'
|
|
2
2
|
require 'iconv'
|
3
3
|
|
4
4
|
require 'nokogiri'
|
5
|
-
require 'bluecloth'
|
5
|
+
# require 'bluecloth'
|
6
6
|
require 'sanitize'
|
7
7
|
|
8
8
|
module TextUtils; end
|
@@ -11,7 +11,7 @@ module TextUtils; end
|
|
11
11
|
support
|
12
12
|
|
13
13
|
processor
|
14
|
-
|
14
|
+
|
15
15
|
ensure_utf
|
16
16
|
html_sanitizer
|
17
17
|
format_qualifier
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class TextUtils::CodeHighlighter < TextUtils::Processor
|
2
2
|
# highlights code inside of <code lang/language='java'> ... code ... </code>
|
3
|
-
def call data, env
|
3
|
+
def call data, env
|
4
4
|
require 'nokogiri'
|
5
5
|
|
6
6
|
snippets = {}
|
@@ -10,22 +10,22 @@ class TextUtils::CodeHighlighter < TextUtils::Processor
|
|
10
10
|
node = Nokogiri::HTML($1 + $3).css('code').first
|
11
11
|
language = node.attributes['lang'].try(:value) || node.attributes['language'].try(:value)
|
12
12
|
code = $2
|
13
|
-
|
14
|
-
if language and code
|
15
|
-
attributes = {}; node.attributes.each{|name, value| attributes[name] = value.value}
|
13
|
+
|
14
|
+
if language and code
|
15
|
+
attributes = {}; node.attributes.each{|name, value| attributes[name] = value.value}
|
16
16
|
code = colorize code, language, attributes
|
17
17
|
cut_snippet snippets, code
|
18
18
|
else
|
19
19
|
$&
|
20
|
-
end
|
20
|
+
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# processign markdown ``` tags
|
24
24
|
data = data.gsub /^```\s*([a-z\-_0-9]+)\s*\n(.+?)^```\s*$/im do
|
25
25
|
language, code = $1, $2
|
26
26
|
|
27
27
|
if language and code
|
28
|
-
code = colorize code, language, {language: language}
|
28
|
+
code = colorize code, language, {language: language}
|
29
29
|
cut_snippet snippets, code
|
30
30
|
else
|
31
31
|
$&
|
@@ -33,18 +33,18 @@ class TextUtils::CodeHighlighter < TextUtils::Processor
|
|
33
33
|
end
|
34
34
|
|
35
35
|
data = call_next data, env
|
36
|
-
|
36
|
+
|
37
37
|
restore_snippet snippets, data
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
protected
|
41
|
-
# temporarilly removing all highlighted code from html to prevent it's beed damaged by next processors
|
41
|
+
# temporarilly removing all highlighted code from html to prevent it's beed damaged by next processors
|
42
42
|
def cut_snippet snippets, code
|
43
43
|
key = "CODESNIPPET#{snippets.size}"
|
44
44
|
snippets[key] = code
|
45
45
|
key
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
# inserting cutted code back to html
|
49
49
|
def restore_snippet snippets, data
|
50
50
|
data = data.gsub /(CODESNIPPET[0-9]+)/ do |key|
|
@@ -52,17 +52,17 @@ class TextUtils::CodeHighlighter < TextUtils::Processor
|
|
52
52
|
end
|
53
53
|
data
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
def colorize code, language, attributes
|
57
57
|
require 'albino'
|
58
|
-
code = Albino.colorize(code, language.to_sym)
|
59
|
-
code = "<code #{attributes.to_a.collect{|k, v| "#{k}='#{v}'"}.join(' ')}>\n#{code}\n</code>"
|
58
|
+
code = Albino.colorize(code, language.to_sym)
|
59
|
+
code = "<code #{attributes.to_a.collect{|k, v| "#{k}='#{v}'"}.join(' ')}>\n#{code}\n</code>"
|
60
60
|
code = rewrite_styles code
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
# adding prefix 'hl_' to all class names
|
64
|
-
def rewrite_styles html
|
65
|
-
node = Nokogiri::HTML(html).css('code').first
|
64
|
+
def rewrite_styles html
|
65
|
+
node = Nokogiri::HTML(html).css('code').first
|
66
66
|
node.css("*").each do |e|
|
67
67
|
classes = e.attribute 'class'
|
68
68
|
if classes and classes.value
|
@@ -5,29 +5,29 @@ class TextUtils::CustomMarkdown < TextUtils::Processor
|
|
5
5
|
image_box data do |data|
|
6
6
|
call_next data, env
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
9
9
|
else
|
10
10
|
call_next data, env
|
11
|
-
end
|
11
|
+
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
protected
|
15
15
|
def hide_html_tags data, &block
|
16
16
|
snippets, counter = {}, 0
|
17
|
-
data = data.gsub /<.+?>/ do
|
17
|
+
data = data.gsub /<.+?>/ do
|
18
18
|
key = "HTMLSNIPPET#{counter}"; counter += 1
|
19
19
|
snippets[key] = $&
|
20
20
|
key
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
data = block.call data
|
24
|
-
|
24
|
+
|
25
25
|
data = data.gsub /HTMLSNIPPET\d+/ do
|
26
26
|
snippets[$&]
|
27
27
|
end
|
28
28
|
data
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
# !![img] => [![img_thumb]][img]
|
32
32
|
def image_box data, &block
|
33
33
|
img_urls = {}
|
@@ -1,14 +1,14 @@
|
|
1
1
|
class TextUtils::EnsureUtf < TextUtils::Processor
|
2
2
|
def call data, env
|
3
3
|
data = call_next data, env
|
4
|
-
|
4
|
+
|
5
5
|
# Escape all non-word unicode symbols, otherwise it will raise error when converting to BSON
|
6
6
|
data = Iconv.conv('UTF-8//IGNORE//TRANSLIT', 'UTF-8', data)
|
7
|
-
|
7
|
+
|
8
8
|
unless data.encoding == Encoding::UTF_8
|
9
9
|
raise "something wrong happens, invalid encoding (#{data.encoding} instead of utf-8)!"
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
data
|
13
13
|
end
|
14
14
|
end
|
@@ -4,9 +4,9 @@ class TextUtils::FormatQualifier < TextUtils::Processor
|
|
4
4
|
(data =~ /\A\s*<[a-z_\-0-9]+>.*<\/[a-z_\-0-9]+>\s*\z/im) or
|
5
5
|
(data =~ /\A\s*<[a-z_\-0-9]+\/>\s*\z/i)
|
6
6
|
) ? :html : :markdown
|
7
|
-
|
7
|
+
|
8
8
|
data = call_next data, env
|
9
|
-
|
9
|
+
|
10
10
|
raise "some processor in pipe clear the data format!" unless env[:format]
|
11
11
|
data
|
12
12
|
end
|
@@ -21,7 +21,7 @@ class TextUtils::HtmlSanitizer < TextUtils::Processor
|
|
21
21
|
'th' => ['abbr', 'axis', 'colspan', 'rowspan', 'scope', 'width'],
|
22
22
|
'ul' => ['type'],
|
23
23
|
'code' => ['lang', 'language'],
|
24
|
-
|
24
|
+
|
25
25
|
'iframe' => ['height', 'scrolling', 'src', 'width']
|
26
26
|
},
|
27
27
|
|
@@ -32,7 +32,7 @@ class TextUtils::HtmlSanitizer < TextUtils::Processor
|
|
32
32
|
'q' => {'cite' => ['http', 'https', :relative]}
|
33
33
|
}
|
34
34
|
}
|
35
|
-
|
35
|
+
|
36
36
|
VIDEO_URLS = [
|
37
37
|
/^http:\/\/(?:www\.)?youtube\.com\/v\//,
|
38
38
|
]
|
@@ -41,11 +41,11 @@ class TextUtils::HtmlSanitizer < TextUtils::Processor
|
|
41
41
|
node = env[:node]
|
42
42
|
node_name = node.name.to_s.downcase
|
43
43
|
parent = node.parent
|
44
|
-
|
44
|
+
|
45
45
|
# Since the transformer receives the deepest nodes first, we look for a
|
46
46
|
# <param> element or an <embed> element whose parent is an <object>.
|
47
47
|
return nil unless (node_name == 'param' || node_name == 'embed') && parent.name.to_s.downcase == 'object'
|
48
|
-
|
48
|
+
|
49
49
|
if node_name == 'param'
|
50
50
|
# Quick XPath search to find the <param> node that contains the video URL.
|
51
51
|
return nil unless movie_node = parent.search('param[@name="movie"]')[0]
|
@@ -55,10 +55,10 @@ class TextUtils::HtmlSanitizer < TextUtils::Processor
|
|
55
55
|
# extra work needed.
|
56
56
|
url = node['src']
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
# # Verify that the video URL is actually a valid YouTube video URL.
|
60
60
|
return nil unless VIDEO_URLS.any?{|t| url =~ t}
|
61
|
-
|
61
|
+
|
62
62
|
# # We're now certain that this is a YouTube embed, but we still need to run
|
63
63
|
# # it through a special Sanitize step to ensure that no unwanted elements or
|
64
64
|
# # attributes that don't belong in a YouTube embed can sneak in.
|
@@ -77,15 +77,15 @@ class TextUtils::HtmlSanitizer < TextUtils::Processor
|
|
77
77
|
# (<object>).
|
78
78
|
{:whitelist_nodes => [node, parent]}
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def call data, env
|
82
82
|
data = call_next data, env
|
83
|
-
|
83
|
+
|
84
84
|
Sanitize.clean(data, RELAXED.merge(
|
85
85
|
transformers: [EMBEDDED_VIDEO],
|
86
86
|
:add_attributes => {
|
87
87
|
all: [:class]
|
88
88
|
}
|
89
|
-
))
|
89
|
+
))
|
90
90
|
end
|
91
91
|
end
|
data/lib/text_utils/markdown.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
class TextUtils::Markdown < TextUtils::Processor
|
2
|
-
DEFAULT_OPTIONS = [:autolink, :lax_htmlblock, :smart, :tables, :xhtml, :fenced_code, :strikethrough, :hard_wrap]
|
3
|
-
|
2
|
+
DEFAULT_OPTIONS = [:autolink, :lax_htmlblock, :smart, :tables, :xhtml, :fenced_code, :strikethrough, :hard_wrap]
|
3
|
+
|
4
4
|
def initialize processor = nil, options = nil
|
5
5
|
super processor
|
6
6
|
@options = options || DEFAULT_OPTIONS
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def call data, env
|
10
10
|
if env[:format] == :markdown
|
11
11
|
require 'redcarpet'
|
12
|
-
|
12
|
+
|
13
13
|
data = fix_new_lines data do |data|
|
14
14
|
markdown = Redcarpet.new(data, *@options)
|
15
15
|
markdown.to_html
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
call_next data, env
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
protected
|
23
23
|
# remove line breaks after images
|
24
24
|
def fix_new_lines data, &block
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
|
27
27
|
data = block.call data
|
28
|
-
|
28
|
+
|
29
29
|
data.gsub /(<img.+?\/>)\s*(<br\s*\/>)\s*\n/ do
|
30
30
|
$1
|
31
31
|
end
|
data/lib/text_utils/pipe.rb
CHANGED
data/lib/text_utils/processor.rb
CHANGED
@@ -2,11 +2,11 @@ class TextUtils::Processor
|
|
2
2
|
def initialize next_processor = nil
|
3
3
|
@next_processor = next_processor
|
4
4
|
end
|
5
|
-
|
5
|
+
|
6
6
|
protected
|
7
7
|
def call_next data, env
|
8
|
-
if @next_processor
|
9
|
-
@next_processor.call data, env
|
8
|
+
if @next_processor
|
9
|
+
@next_processor.call data, env
|
10
10
|
else
|
11
11
|
data
|
12
12
|
end
|
data/lib/text_utils/support.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Object.class_eval do
|
2
2
|
unless method_defined? :try
|
3
|
-
def try method
|
4
|
-
self && self.send(method)
|
3
|
+
def try method, *args, &block
|
4
|
+
self && self.send(method, *args, &block)
|
5
5
|
end
|
6
6
|
end
|
7
7
|
end
|
@@ -11,5 +11,5 @@ class String
|
|
11
11
|
def self.random length = 3
|
12
12
|
@digits ||= ('a'..'z').to_a + (0..9).to_a
|
13
13
|
(0..(length-1)).map{@digits[rand(@digits.size)]}.join
|
14
|
-
end
|
14
|
+
end
|
15
15
|
end
|
data/lib/text_utils/truncate.rb
CHANGED
@@ -3,15 +3,15 @@ class TextUtils::Truncate < TextUtils::Processor
|
|
3
3
|
super processor
|
4
4
|
@length = length
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
def call data, env
|
8
8
|
data ||= ""
|
9
|
-
|
9
|
+
|
10
10
|
# strip from HTML tags
|
11
11
|
data = data.gsub("<br", " <br").gsub("<p", " <p") # to preserve space in place of <> html elements
|
12
12
|
doc = Nokogiri::XML("<div class='root'>#{data}</div>")
|
13
13
|
data = doc.css('.root').first.content
|
14
|
-
|
14
|
+
|
15
15
|
# remove clear space
|
16
16
|
data = data.gsub(/\s+/, ' ')
|
17
17
|
|
@@ -24,7 +24,7 @@ class TextUtils::Truncate < TextUtils::Processor
|
|
24
24
|
else
|
25
25
|
data
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
call_next data, env
|
29
29
|
end
|
30
30
|
end
|
data/readme.md
CHANGED