danwrong-evil 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -0
- data/Manifest +11 -1
- data/README.textile +48 -10
- data/Rakefile +2 -1
- data/assets/evil-lib.js +306 -7
- data/assets/evil.css +9 -1
- data/assets/evil.js +22 -1
- data/evil.gemspec +5 -5
- data/lib/evil/application.rb +17 -1
- data/lib/evil/helpers.rb +1 -1
- data/lib/evil/models/template.rb +1 -1
- data/lib/evil/plugin.rb +4 -0
- data/lib/evil/plugin/base.rb +2 -2
- data/lib/evil/plugin/block_tag.rb +48 -0
- data/lib/evil/plugin/configuration.rb +4 -8
- data/lib/evil/plugin/filesystem.rb +1 -1
- data/lib/evil/plugin/singleton_tag.rb +18 -0
- data/lib/evil/plugin/tag.rb +18 -52
- data/test/application/frontend_test.rb +52 -0
- data/test/{app/evil_test.rb → application/openid_test.rb} +5 -23
- data/test/application/plugin_config_test.rb +73 -0
- data/test/application/template_test.rb +119 -0
- data/test/test_helper.rb +26 -1
- data/test/units/models/template_test.rb +16 -0
- data/test/units/models/whitelist_test.rb +31 -0
- data/test/units/plugin/base_test.rb +27 -2
- data/test/units/plugin/configuration_test.rb +60 -0
- data/test/units/plugin/environment_test.rb +13 -0
- data/test/units/plugin/filesystem_test.rb +22 -0
- data/test/units/plugin/tag_test.rb +36 -7
- data/views/index.haml +2 -2
- metadata +24 -4
data/assets/evil.js
CHANGED
@@ -15,6 +15,27 @@ jQuery(function($) {
|
|
15
15
|
}
|
16
16
|
});
|
17
17
|
|
18
|
+
var TemplateReorder = $.klass({
|
19
|
+
initialize: function() {
|
20
|
+
this.element.tableDnD({
|
21
|
+
onDrop: $.bind(this._onDrop, this),
|
22
|
+
onDragClass: 'dragging'
|
23
|
+
});
|
24
|
+
},
|
25
|
+
_onDrop: function() {
|
26
|
+
var data = $.tableDnD.serialize();
|
27
|
+
|
28
|
+
$.post('/admin/templates/reorder', data);
|
29
|
+
|
30
|
+
this._restripe();
|
31
|
+
},
|
32
|
+
_restripe: function() {
|
33
|
+
this.element.find('tbody tr:odd').addClass('alt');
|
34
|
+
this.element.find('tbody tr:even').removeClass('alt');
|
35
|
+
}
|
36
|
+
})
|
37
|
+
|
18
38
|
|
19
|
-
$(window).attach(Sizer, 1000, 'wide')
|
39
|
+
$(window).attach(Sizer, 1000, 'wide');
|
40
|
+
$('#templates').attach(TemplateReorder);
|
20
41
|
});
|
data/evil.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{evil}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Dan Webb"]
|
9
|
-
s.date = %q{2009-04-
|
9
|
+
s.date = %q{2009-04-22}
|
10
10
|
s.default_executable = %q{evil}
|
11
11
|
s.description = %q{A simple framework for creating sites from 3rd party data and services}
|
12
12
|
s.email = %q{dan@danwebb.net}
|
13
13
|
s.executables = ["evil"]
|
14
|
-
s.extra_rdoc_files = ["bin/evil", "CHANGELOG", "lib/evil/application.rb", "lib/evil/extensions.rb", "lib/evil/helpers.rb", "lib/evil/models/config_pair.rb", "lib/evil/models/template.rb", "lib/evil/models/whitelist.rb", "lib/evil/models.rb", "lib/evil/open_id.rb", "lib/evil/plugin/base.rb", "lib/evil/plugin/configuration.rb", "lib/evil/plugin/environment.rb", "lib/evil/plugin/filesystem.rb", "lib/evil/plugin/tag.rb", "lib/evil/plugin.rb", "lib/evil/setup/db_tool.rb", "lib/evil/setup/generator.rb", "lib/evil/setup/migration.rb", "lib/evil.rb", "LICENSE", "README.textile"]
|
15
|
-
s.files = ["assets/config.ru", "assets/evil-lib.js", "assets/evil.css", "assets/evil.js", "assets/logo.png", "bin/evil", "CHANGELOG", "evil.gemspec", "lib/evil/application.rb", "lib/evil/extensions.rb", "lib/evil/helpers.rb", "lib/evil/models/config_pair.rb", "lib/evil/models/template.rb", "lib/evil/models/whitelist.rb", "lib/evil/models.rb", "lib/evil/open_id.rb", "lib/evil/plugin/base.rb", "lib/evil/plugin/configuration.rb", "lib/evil/plugin/environment.rb", "lib/evil/plugin/filesystem.rb", "lib/evil/plugin/tag.rb", "lib/evil/plugin.rb", "lib/evil/setup/db_tool.rb", "lib/evil/setup/generator.rb", "lib/evil/setup/migration.rb", "lib/evil.rb", "LICENSE", "Manifest", "Rakefile", "README.textile", "test/
|
14
|
+
s.extra_rdoc_files = ["bin/evil", "CHANGELOG", "lib/evil/application.rb", "lib/evil/extensions.rb", "lib/evil/helpers.rb", "lib/evil/models/config_pair.rb", "lib/evil/models/template.rb", "lib/evil/models/whitelist.rb", "lib/evil/models.rb", "lib/evil/open_id.rb", "lib/evil/plugin/base.rb", "lib/evil/plugin/block_tag.rb", "lib/evil/plugin/configuration.rb", "lib/evil/plugin/environment.rb", "lib/evil/plugin/filesystem.rb", "lib/evil/plugin/singleton_tag.rb", "lib/evil/plugin/tag.rb", "lib/evil/plugin.rb", "lib/evil/setup/db_tool.rb", "lib/evil/setup/generator.rb", "lib/evil/setup/migration.rb", "lib/evil.rb", "LICENSE", "README.textile"]
|
15
|
+
s.files = ["assets/config.ru", "assets/evil-lib.js", "assets/evil.css", "assets/evil.js", "assets/logo.png", "bin/evil", "CHANGELOG", "evil.gemspec", "lib/evil/application.rb", "lib/evil/extensions.rb", "lib/evil/helpers.rb", "lib/evil/models/config_pair.rb", "lib/evil/models/template.rb", "lib/evil/models/whitelist.rb", "lib/evil/models.rb", "lib/evil/open_id.rb", "lib/evil/plugin/base.rb", "lib/evil/plugin/block_tag.rb", "lib/evil/plugin/configuration.rb", "lib/evil/plugin/environment.rb", "lib/evil/plugin/filesystem.rb", "lib/evil/plugin/singleton_tag.rb", "lib/evil/plugin/tag.rb", "lib/evil/plugin.rb", "lib/evil/setup/db_tool.rb", "lib/evil/setup/generator.rb", "lib/evil/setup/migration.rb", "lib/evil.rb", "LICENSE", "Manifest", "Rakefile", "README.textile", "test/application/frontend_test.rb", "test/application/openid_test.rb", "test/application/plugin_config_test.rb", "test/application/template_test.rb", "test/dev_env.rb", "test/test_helper.rb", "test/units/models/template_test.rb", "test/units/models/whitelist_test.rb", "test/units/plugin/base_test.rb", "test/units/plugin/configuration_test.rb", "test/units/plugin/environment_test.rb", "test/units/plugin/filesystem_test.rb", "test/units/plugin/tag_test.rb", "views/_banner.haml", "views/_errors.haml", "views/index.haml", "views/layout.haml", "views/login.haml", "views/plugins/_fields.haml", "views/plugins/edit.haml", "views/plugins/fields/_password.haml", "views/plugins/fields/_text.haml", "views/plugins/new.haml", "views/templates/_fields.haml", "views/templates/edit.haml", "views/templates/new.haml"]
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.homepage = %q{http://www.evilmashups.com}
|
18
18
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Evil", "--main", "README.textile"]
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.rubyforge_project = %q{evil}
|
21
21
|
s.rubygems_version = %q{1.3.1}
|
22
22
|
s.summary = %q{A simple framework for creating sites from 3rd party data and services}
|
23
|
-
s.test_files = ["test/
|
23
|
+
s.test_files = ["test/application/frontend_test.rb", "test/application/openid_test.rb", "test/application/plugin_config_test.rb", "test/application/template_test.rb", "test/test_helper.rb", "test/units/models/template_test.rb", "test/units/models/whitelist_test.rb", "test/units/plugin/base_test.rb", "test/units/plugin/configuration_test.rb", "test/units/plugin/environment_test.rb", "test/units/plugin/filesystem_test.rb", "test/units/plugin/tag_test.rb"]
|
24
24
|
|
25
25
|
if s.respond_to? :specification_version then
|
26
26
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
data/lib/evil/application.rb
CHANGED
@@ -10,7 +10,6 @@ module Evil
|
|
10
10
|
end
|
11
11
|
|
12
12
|
require_whitelisted_openid(/^\/admin/)
|
13
|
-
load_template_routes
|
14
13
|
|
15
14
|
get '/admin/openid/login' do
|
16
15
|
attempt_openid_authentication do |identity_url|
|
@@ -47,6 +46,21 @@ module Evil
|
|
47
46
|
haml :"templates/new"
|
48
47
|
end
|
49
48
|
end
|
49
|
+
|
50
|
+
post '/admin/templates/reorder' do
|
51
|
+
order = params[:templates].collect do |id|
|
52
|
+
if id =~ /(\d)+t/
|
53
|
+
$1.to_i
|
54
|
+
end
|
55
|
+
end.compact
|
56
|
+
|
57
|
+
|
58
|
+
order.each_with_index do |id, i|
|
59
|
+
Evil::Models::Template.find(id).update_attribute :position, i
|
60
|
+
end
|
61
|
+
|
62
|
+
order.join(',')
|
63
|
+
end
|
50
64
|
|
51
65
|
get '/admin/templates/:id' do
|
52
66
|
@template = Evil::Models::Template.find(params[:id]) rescue not_found
|
@@ -84,6 +98,8 @@ module Evil
|
|
84
98
|
|
85
99
|
redirect '/admin'
|
86
100
|
end
|
101
|
+
|
102
|
+
load_template_routes
|
87
103
|
end
|
88
104
|
end
|
89
105
|
|
data/lib/evil/helpers.rb
CHANGED
data/lib/evil/models/template.rb
CHANGED
@@ -6,7 +6,7 @@ module Evil
|
|
6
6
|
set_table_name :evil_templates
|
7
7
|
|
8
8
|
validates_presence_of :title, :source
|
9
|
-
validates_uniqueness_of :route, :if => lambda { |template| !(template.route.
|
9
|
+
validates_uniqueness_of :route, :if => lambda { |template| !(template.route.nil? || template.route.empty?) }
|
10
10
|
validates_format_of :route, :with => /^((\/)|(((\/|\.):?[a-z0-9\_]+)+))$/,
|
11
11
|
:allow_blank => true, :allow_nil => true
|
12
12
|
validate :liquid_syntax
|
data/lib/evil/plugin.rb
CHANGED
@@ -2,12 +2,16 @@ module Evil
|
|
2
2
|
module Plugin
|
3
3
|
autoload :Base, 'evil/plugin/base'
|
4
4
|
autoload :Tag, 'evil/plugin/tag'
|
5
|
+
autoload :BlockTag, 'evil/plugin/block_tag'
|
6
|
+
autoload :SingletonTag, 'evil/plugin/singleton_tag'
|
5
7
|
autoload :Environment, 'evil/plugin/environment'
|
6
8
|
autoload :Filesystem, 'evil/plugin/filesystem'
|
7
9
|
autoload :Configuration, 'evil/plugin/configuration'
|
8
10
|
|
9
11
|
def self.evaluate(plugin_source)
|
10
12
|
Environment.module_eval plugin_source
|
13
|
+
rescue
|
14
|
+
nil
|
11
15
|
end
|
12
16
|
|
13
17
|
def self.from_file(file)
|
data/lib/evil/plugin/base.rb
CHANGED
@@ -22,8 +22,8 @@ module Evil
|
|
22
22
|
@setup_proc = block
|
23
23
|
end
|
24
24
|
|
25
|
-
def tag(name, &block)
|
26
|
-
tag =
|
25
|
+
def tag(name, options={}, &block)
|
26
|
+
tag = options[:block] ? BlockTag.from(&block) : SingletonTag.from(&block)
|
27
27
|
Liquid::Template.register_tag(name, tag)
|
28
28
|
end
|
29
29
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Evil
|
2
|
+
module Plugin
|
3
|
+
|
4
|
+
class TagExecution
|
5
|
+
|
6
|
+
def initialize(tag, options, context, &block)
|
7
|
+
@options = Tag.evaluate(options, context)
|
8
|
+
@context = context
|
9
|
+
@tag = tag
|
10
|
+
@proc = block
|
11
|
+
end
|
12
|
+
|
13
|
+
def body(locals={})
|
14
|
+
@context.stack do
|
15
|
+
locals.each { |k, v| @context[k.to_s] = v }
|
16
|
+
return @tag.render_body(@context).to_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
self.instance_exec(@options, &@proc)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
execute.to_s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class BlockTag < Liquid::Block
|
30
|
+
include Tag
|
31
|
+
|
32
|
+
def initialize(tag_name, markup, tokens)
|
33
|
+
super
|
34
|
+
|
35
|
+
set_options(markup)
|
36
|
+
end
|
37
|
+
|
38
|
+
def render(context)
|
39
|
+
TagExecution.new(self, @options, context, &self.class.tag_proc).to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def render_body(context)
|
43
|
+
render_all(@nodelist, context)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -49,8 +49,8 @@ module Evil
|
|
49
49
|
|
50
50
|
def set(values)
|
51
51
|
values.each do |k, v|
|
52
|
-
c = ConfigPair.find_or_create_by_plugin_and_key(@plugin.name, k)
|
53
|
-
c.update_attribute :value, v
|
52
|
+
c = ConfigPair.find_or_create_by_plugin_and_key(@plugin.name, k.to_s)
|
53
|
+
c.update_attribute :value, v.to_s
|
54
54
|
end if values
|
55
55
|
|
56
56
|
load_config!
|
@@ -61,12 +61,8 @@ module Evil
|
|
61
61
|
def load_config!
|
62
62
|
pairs = Evil::Models::ConfigPair.find_all_by_plugin(@plugin.name)
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
m[pair.key.to_sym] = pair.value; m
|
67
|
-
end
|
68
|
-
else
|
69
|
-
@values = Hash.new('')
|
64
|
+
@values = pairs.inject(Hash.new('')) do |m, pair|
|
65
|
+
m[pair.key.to_sym] = pair.value; m
|
70
66
|
end
|
71
67
|
end
|
72
68
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Evil
|
2
|
+
module Plugin
|
3
|
+
class SingletonTag < Liquid::Tag
|
4
|
+
include Tag
|
5
|
+
|
6
|
+
def initialize(tag_name, markup, tokens)
|
7
|
+
super
|
8
|
+
|
9
|
+
set_options(markup)
|
10
|
+
end
|
11
|
+
|
12
|
+
def render(context)
|
13
|
+
self.class.tag_proc.call(Tag.evaluate(@options, context))
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/evil/plugin/tag.rb
CHANGED
@@ -1,56 +1,32 @@
|
|
1
1
|
module Evil
|
2
2
|
module Plugin
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
def initialize(tag, options, context, &block)
|
7
|
-
@options = evaluate(options, context)
|
8
|
-
@context = context
|
9
|
-
@tag = tag
|
10
|
-
@proc = block
|
11
|
-
end
|
3
|
+
module Tag
|
4
|
+
Syntax = /((#{Liquid::TagAttributes}\s?,?\s?)*)/
|
12
5
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
def self.included(base)
|
7
|
+
base.instance_eval do
|
8
|
+
def from(&block)
|
9
|
+
tag = Class.new(self)
|
10
|
+
|
11
|
+
class << tag
|
12
|
+
attr_accessor :tag_proc
|
13
|
+
end
|
14
|
+
|
15
|
+
tag.tag_proc = block; tag
|
16
|
+
end
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
self.instance_exec(@options, &@proc)
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_s
|
25
|
-
execute.to_s
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def evaluate(options, context)
|
20
|
+
def self.evaluate(options, context)
|
31
21
|
options.inject({}) do |evaluated, pair|
|
32
22
|
opt, value = pair
|
33
23
|
evaluated[opt] = context[value]; evaluated
|
34
24
|
end
|
35
25
|
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class Tag < Liquid::Block
|
39
|
-
Syntax = /((#{Liquid::TagAttributes}\s?,?\s?)*)/
|
40
26
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
def from(&block)
|
46
|
-
tag = Class.new(self)
|
47
|
-
tag.tag_proc = block; tag
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def initialize(tag_name, markup, tokens)
|
52
|
-
super
|
53
|
-
|
27
|
+
protected
|
28
|
+
|
29
|
+
def set_options(markup)
|
54
30
|
if markup =~ Syntax
|
55
31
|
@options = parse_options($1)
|
56
32
|
else
|
@@ -58,16 +34,6 @@ module Evil
|
|
58
34
|
end
|
59
35
|
end
|
60
36
|
|
61
|
-
def render(context)
|
62
|
-
TagExecution.new(self, @options, context, &self.class.tag_proc).to_s
|
63
|
-
end
|
64
|
-
|
65
|
-
def render_body(context)
|
66
|
-
render_all(@nodelist, context)
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
37
|
def parse_options(opt_string)
|
72
38
|
pairs = opt_string.split(',')
|
73
39
|
pairs.inject({}) do |opts, pair|
|
@@ -75,7 +41,7 @@ module Evil
|
|
75
41
|
opts[opt.strip.to_sym] = value.strip; opts
|
76
42
|
end
|
77
43
|
end
|
44
|
+
|
78
45
|
end
|
79
|
-
|
80
46
|
end
|
81
47
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
require 'evil/application'
|
3
|
+
|
4
|
+
class FrontendTest < Test::Unit::TestCase
|
5
|
+
include Sinatra::Test
|
6
|
+
|
7
|
+
context 'running the evil application' do
|
8
|
+
setup do
|
9
|
+
@app = Evil::Application
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
context 'GET a template page' do
|
14
|
+
setup do
|
15
|
+
@template = Factory.create(:template)
|
16
|
+
@app.reload!
|
17
|
+
get @template.route
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'be successful' do
|
21
|
+
assert_equal 200, response.status
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'render with text/html as default content_type' do
|
25
|
+
assert_match /text\/html/, response.headers['Content-Type']
|
26
|
+
assert_match /utf-8/, response.headers['Content-Type']
|
27
|
+
end
|
28
|
+
|
29
|
+
should 'set a Cache-Control header from the template\'s ttl' do
|
30
|
+
assert_match /max-age=#{@template.ttl}/, response.headers['Cache-Control']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'GET a template page with another content type set' do
|
35
|
+
setup do
|
36
|
+
@template = Factory.create(:template, :content_type => 'application/xml')
|
37
|
+
@app.reload!
|
38
|
+
get @template.route
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'be successful' do
|
42
|
+
assert_equal 200, response.status
|
43
|
+
end
|
44
|
+
|
45
|
+
should 'render with text/html as default content_type' do
|
46
|
+
assert_match /application\/xml/, response.headers['Content-Type']
|
47
|
+
assert_match /utf-8/, response.headers['Content-Type']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
2
|
require 'evil/application'
|
3
3
|
|
4
|
-
class
|
4
|
+
class OpenidTest < Test::Unit::TestCase
|
5
5
|
include Sinatra::Test
|
6
6
|
|
7
7
|
context 'running the evil application' do
|
@@ -21,12 +21,14 @@ class EvilTest < Test::Unit::TestCase
|
|
21
21
|
assert_match /openid_url/, response.body
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
end
|
26
|
+
|
26
27
|
|
27
28
|
context 'while logged in' do
|
28
29
|
setup do
|
29
|
-
|
30
|
+
Factory.create(:whitelist)
|
31
|
+
@env = { 'rack.session' => { :identity_url => 'www.example.com' } }
|
30
32
|
end
|
31
33
|
|
32
34
|
context 'GET /admin' do
|
@@ -38,26 +40,6 @@ class EvilTest < Test::Unit::TestCase
|
|
38
40
|
assert response.ok?
|
39
41
|
end
|
40
42
|
end
|
41
|
-
|
42
|
-
context 'GET /admin/templates/1 with existing template' do
|
43
|
-
setup do
|
44
|
-
get '/admin/templates/1', {}, @env
|
45
|
-
end
|
46
|
-
|
47
|
-
should 'be successful' do
|
48
|
-
assert response.ok?
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'GET /admin/templates/nothinghere with non-existing template' do
|
53
|
-
setup do
|
54
|
-
get '/admin/templates/nothinghere', {}, @env
|
55
|
-
end
|
56
|
-
|
57
|
-
should 'be not found' do
|
58
|
-
assert_equal 404, response.status
|
59
|
-
end
|
60
|
-
end
|
61
43
|
end
|
62
44
|
end
|
63
45
|
|