danwrong-evil 0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/CHANGELOG +1 -0
  2. data/LICENSE +22 -0
  3. data/Manifest +33 -7
  4. data/README.textile +20 -0
  5. data/Rakefile +21 -2
  6. data/assets/config.ru +10 -2
  7. data/assets/evil-lib.js +222 -0
  8. data/assets/evil.css +204 -10
  9. data/assets/evil.js +20 -0
  10. data/assets/logo.png +0 -0
  11. data/evil.gemspec +32 -19
  12. data/lib/evil/application.rb +85 -17
  13. data/lib/evil/extensions.rb +71 -0
  14. data/lib/evil/helpers.rb +62 -0
  15. data/lib/evil/models/config_pair.rb +7 -0
  16. data/lib/evil/models/template.rb +10 -9
  17. data/lib/evil/models.rb +0 -12
  18. data/lib/evil/open_id.rb +101 -0
  19. data/lib/evil/plugin/base.rb +56 -0
  20. data/lib/evil/plugin/configuration.rb +77 -0
  21. data/lib/evil/plugin/environment.rb +15 -0
  22. data/lib/evil/plugin/filesystem.rb +18 -0
  23. data/lib/evil/plugin/tag.rb +81 -0
  24. data/lib/evil/plugin.rb +21 -0
  25. data/lib/evil/setup/generator.rb +13 -1
  26. data/lib/evil/setup/migration.rb +4 -11
  27. data/lib/evil.rb +34 -1
  28. data/test/app/evil_test.rb +64 -0
  29. data/test/dev_env.rb +10 -0
  30. data/test/test_helper.rb +12 -0
  31. data/test/units/plugin/base_test.rb +47 -0
  32. data/test/units/plugin/tag_test.rb +108 -0
  33. data/views/_banner.haml +8 -0
  34. data/views/_errors.haml +9 -0
  35. data/views/index.haml +41 -0
  36. data/views/layout.haml +13 -0
  37. data/views/login.haml +5 -0
  38. data/views/plugins/_fields.haml +7 -0
  39. data/views/plugins/edit.haml +2 -0
  40. data/views/plugins/fields/_password.haml +3 -0
  41. data/views/plugins/fields/_text.haml +3 -0
  42. data/views/plugins/new.haml +6 -0
  43. data/views/templates/_fields.haml +23 -0
  44. data/views/templates/edit.haml +3 -0
  45. data/views/templates/new.haml +3 -0
  46. metadata +115 -13
  47. data/lib/evil/models/plugin.rb +0 -13
  48. data/test/harness/config.ru +0 -9
  49. data/test/harness/evil.db +0 -0
  50. data/test/harness/public/javascripts/evil.js +0 -0
  51. data/test/harness/public/stylesheets/evil.css +0 -24
  52. data/test/harness/tmp/restart.txt +0 -0
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.1"
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-03-18}
9
+ s.date = %q{2009-04-17}
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/models/config_pair.rb", "lib/evil/models/plugin.rb", "lib/evil/models/template.rb", "lib/evil/models/whitelist.rb", "lib/evil/models.rb", "lib/evil/setup/db_tool.rb", "lib/evil/setup/generator.rb", "lib/evil/setup/migration.rb", "lib/evil.rb"]
15
- s.files = ["assets/config.ru", "assets/evil.css", "assets/evil.js", "bin/evil", "CHANGELOG", "lib/evil/application.rb", "lib/evil/models/config_pair.rb", "lib/evil/models/plugin.rb", "lib/evil/models/template.rb", "lib/evil/models/whitelist.rb", "lib/evil/models.rb", "lib/evil/setup/db_tool.rb", "lib/evil/setup/generator.rb", "lib/evil/setup/migration.rb", "lib/evil.rb", "Rakefile", "test/harness/config.ru", "test/harness/evil.db", "test/harness/public/javascripts/evil.js", "test/harness/public/stylesheets/evil.css", "test/harness/tmp/restart.txt", "Manifest", "evil.gemspec"]
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/app/evil_test.rb", "test/dev_env.rb", "test/test_helper.rb", "test/units/plugin/base_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,29 +20,42 @@ 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/app/evil_test.rb", "test/test_helper.rb", "test/units/plugin/base_test.rb", "test/units/plugin/tag_test.rb"]
23
24
 
24
25
  if s.respond_to? :specification_version then
25
26
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
27
  s.specification_version = 2
27
28
 
28
29
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
- s.add_runtime_dependency(%q<sinatra>, [">= 0"])
30
- s.add_runtime_dependency(%q<activerecord>, [">= 0"])
31
- s.add_runtime_dependency(%q<sqlite3-ruby>, [">= 0"])
32
- s.add_runtime_dependency(%q<clip>, [">= 0"])
33
- s.add_runtime_dependency(%q<haml>, [">= 0"])
30
+ s.add_runtime_dependency(%q<sinatra>, [">= 0", "= 0.9.1.1"])
31
+ s.add_runtime_dependency(%q<activerecord>, [">= 0", "= 2.3.2"])
32
+ s.add_runtime_dependency(%q<sqlite3-ruby>, [">= 0", "= 1.2.1"])
33
+ s.add_runtime_dependency(%q<clip>, [">= 0", "= 1.0.0"])
34
+ s.add_runtime_dependency(%q<haml>, [">= 0", "= 2.0.9"])
35
+ s.add_runtime_dependency(%q<liquid>, [">= 0", "= 2.0.0"])
36
+ s.add_runtime_dependency(%q<danwrong-liquid-inheritance>, [">= 0", "= 0.1.1"])
37
+ s.add_runtime_dependency(%q<rack-cache>, [">= 0", "= 0.4"])
38
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
34
39
  else
35
- s.add_dependency(%q<sinatra>, [">= 0"])
36
- s.add_dependency(%q<activerecord>, [">= 0"])
37
- s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
38
- s.add_dependency(%q<clip>, [">= 0"])
39
- s.add_dependency(%q<haml>, [">= 0"])
40
+ s.add_dependency(%q<sinatra>, [">= 0", "= 0.9.1.1"])
41
+ s.add_dependency(%q<activerecord>, [">= 0", "= 2.3.2"])
42
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0", "= 1.2.1"])
43
+ s.add_dependency(%q<clip>, [">= 0", "= 1.0.0"])
44
+ s.add_dependency(%q<haml>, [">= 0", "= 2.0.9"])
45
+ s.add_dependency(%q<liquid>, [">= 0", "= 2.0.0"])
46
+ s.add_dependency(%q<danwrong-liquid-inheritance>, [">= 0", "= 0.1.1"])
47
+ s.add_dependency(%q<rack-cache>, [">= 0", "= 0.4"])
48
+ s.add_dependency(%q<shoulda>, [">= 0"])
40
49
  end
41
50
  else
42
- s.add_dependency(%q<sinatra>, [">= 0"])
43
- s.add_dependency(%q<activerecord>, [">= 0"])
44
- s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
45
- s.add_dependency(%q<clip>, [">= 0"])
46
- s.add_dependency(%q<haml>, [">= 0"])
51
+ s.add_dependency(%q<sinatra>, [">= 0", "= 0.9.1.1"])
52
+ s.add_dependency(%q<activerecord>, [">= 0", "= 2.3.2"])
53
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0", "= 1.2.1"])
54
+ s.add_dependency(%q<clip>, [">= 0", "= 1.0.0"])
55
+ s.add_dependency(%q<haml>, [">= 0", "= 2.0.9"])
56
+ s.add_dependency(%q<liquid>, [">= 0", "= 2.0.0"])
57
+ s.add_dependency(%q<danwrong-liquid-inheritance>, [">= 0", "= 0.1.1"])
58
+ s.add_dependency(%q<rack-cache>, [">= 0", "= 0.4"])
59
+ s.add_dependency(%q<shoulda>, [">= 0"])
47
60
  end
48
61
  end
@@ -1,21 +1,89 @@
1
- require 'sinatra'
2
- require 'evil/models'
3
-
4
- configure do
5
- Sinatra.register Evil::Models
6
-
7
- set :sessions => true,
8
- :static => File.join(Evil.app_root, 'public'),
9
- :views => File.join(Evil.gem_root, 'views'),
10
- :haml => { :format => :html5 }
11
-
12
- connect_to_database
13
- end
1
+ require 'sinatra/base'
2
+
3
+ module Evil
4
+ class Application < Sinatra::Base
5
+ configure do
6
+ register(Evil::Extensions)
7
+ helpers(Evil::Helpers, Evil::OpenID::Helpers)
8
+
9
+ initialize_evil
10
+ end
11
+
12
+ require_whitelisted_openid(/^\/admin/)
13
+ load_template_routes
14
+
15
+ get '/admin/openid/login' do
16
+ attempt_openid_authentication do |identity_url|
17
+ session[:identity_url] = identity_url
18
+ redirect session[:destination_url]
19
+ end
20
+ end
21
+
22
+ post '/admin/openid/logout' do
23
+ session[:identity_url] = nil
24
+ redirect '/admin'
25
+ end
26
+
27
+ get '/admin' do
28
+ @templates = Evil::Models::Template.in_order
29
+ @plugins = Evil::Models::ConfigPair.plugins
30
+
31
+ haml :index
32
+ end
33
+
34
+ get '/admin/templates/new' do
35
+ @template = Evil::Models::Template.new
14
36
 
15
- include Evil::Models
37
+ haml :"templates/new"
38
+ end
16
39
 
17
- get '/admin' do
18
- @thing = Whitelist.find(:first).pattern
19
- haml :index
40
+ post '/admin/templates' do
41
+ @template = Evil::Models::Template.new params[:template]
42
+
43
+ if @template.save
44
+ self.class.reload!
45
+ redirect '/admin'
46
+ else
47
+ haml :"templates/new"
48
+ end
49
+ end
50
+
51
+ get '/admin/templates/:id' do
52
+ @template = Evil::Models::Template.find(params[:id]) rescue not_found
53
+
54
+ haml :"templates/edit"
55
+ end
56
+
57
+ post '/admin/templates/:id' do
58
+ @template = Evil::Models::Template.find(params[:id]) rescue not_found
59
+
60
+ @template.attributes = params[:template]
61
+
62
+ if @template.save
63
+ self.class.reload!
64
+ redirect '/admin'
65
+ else
66
+ haml :"templates/edit"
67
+ end
68
+ end
69
+
70
+ get '/admin/plugins/new' do
71
+ haml :"plugins/new"
72
+ end
73
+
74
+ get '/admin/plugins/:id' do
75
+ @plugin = Evil::Plugin.find_plugin(params[:id]) rescue not_found
76
+
77
+ haml :"plugins/edit"
78
+ end
79
+
80
+ post '/admin/plugins/:id' do
81
+ @plugin = Evil::Plugin.find_plugin(params[:id]) rescue not_found
82
+
83
+ @plugin.config.set(params[:config])
84
+
85
+ redirect '/admin'
86
+ end
87
+ end
20
88
  end
21
89
 
@@ -0,0 +1,71 @@
1
+ require 'evil/models'
2
+
3
+ module Evil
4
+ module Extensions
5
+
6
+ def initialize_evil
7
+ set :public => File.join(Evil.app_root, 'public'),
8
+ :views => File.join(Evil.gem_root, 'views'),
9
+ :haml => { :format => :html5 },
10
+ :logging => true,
11
+ :static => true,
12
+ :dump_errors => true
13
+
14
+ Liquid::Template.file_system = Evil::Plugin::Filesystem.new
15
+
16
+ connect_to_database
17
+ load_all_plugins
18
+ end
19
+
20
+ def reload!
21
+ @reloading = true
22
+ reset!
23
+ Kernel.load 'evil/application.rb'
24
+ @reloading = false
25
+ end
26
+
27
+ def connect_to_database
28
+ if Evil.heroku?
29
+ dbconfig = YAML.load(File.read(File.join(Evil.app_root, 'config/database.yml')))
30
+ ActiveRecord::Base.establish_connection dbconfig['production']
31
+ else
32
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3',
33
+ :database => File.join(Evil.app_root, 'evil.db')
34
+ end
35
+ end
36
+
37
+ def load_template_routes
38
+ Evil::Models::Template.in_order.each do |template|
39
+ get(template.route, &proc_for(template)) unless template.route.nil? || template.route.empty?
40
+ end
41
+ end
42
+
43
+ def load_all_plugins
44
+ Dir[File.join(Evil.gem_root, 'lib', 'plugin/builtin', '*.rb')].each do |plugin|
45
+ Evil::Plugin.from_file(plugin)
46
+ end
47
+
48
+ Dir[File.join(Evil.app_root, 'plugins', '*.evil')].each do |plugin|
49
+ Evil::Plugin.from_file(plugin)
50
+ end
51
+ end
52
+
53
+ def require_whitelisted_openid(pattern)
54
+ before do
55
+ if request.path_info =~ pattern && !params[:openid_url]
56
+ unless whitelisted_openid?
57
+ session[:destination_url] = request.url
58
+ not_authorized
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ protected
65
+
66
+ def proc_for(template)
67
+ lambda { serve template }
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,62 @@
1
+ module Evil
2
+ module Helpers
3
+ include Evil::Models
4
+
5
+ def serve(template)
6
+ initialize_plugins
7
+
8
+ liquid_template = Liquid::Template.parse(template.reload.source)
9
+
10
+ content_type(template.content_type || 'text/html', :charset => template.encoding || 'utf-8')
11
+
12
+ if template.ttl
13
+ headers 'Cache-Control' => "public, max-age=#{template.ttl}"
14
+ end
15
+
16
+ liquid_template.render 'params' => params
17
+ end
18
+
19
+ def partial(template, options={})
20
+ haml(partial_name(template), options.merge( :layout => false ))
21
+ end
22
+
23
+ def render_config_field(field)
24
+ partial("plugins/fields/#{field.type}", :locals => { :field => field })
25
+ end
26
+
27
+ def not_authorized(message=nil)
28
+ status 401
29
+ halt haml(:login)
30
+ end
31
+
32
+ def whitelisted_openid?
33
+ session[:identity_url] && Whitelist.authorize(session[:identity_url])
34
+ end
35
+
36
+ def attempt_openid_authentication
37
+ openid_authenticate do |result, identity_url|
38
+ if result == :successful
39
+ yield identity_url
40
+ else
41
+ not_authorized
42
+ end
43
+ end
44
+ end
45
+
46
+ def urlencode(str)
47
+ URI.escape(str)
48
+ end
49
+
50
+ protected
51
+
52
+ def initialize_plugins
53
+ Plugin::Environment.plugins.each { |p| p.init }
54
+ end
55
+
56
+ def partial_name(template_path)
57
+ parts = template_path.to_s.split('/')
58
+ parts[-1] = "_#{parts.last}"
59
+ parts.join('/').to_sym
60
+ end
61
+ end
62
+ end
@@ -4,6 +4,13 @@ module Evil
4
4
 
5
5
  class ConfigPair < ActiveRecord::Base
6
6
  set_table_name :evil_config_pairs
7
+
8
+ def self.plugins
9
+ find_by_sql('SELECT DISTINCT(plugin) from evil_config_pairs').collect do |p|
10
+ p.plugin
11
+ end
12
+ end
13
+
7
14
  end
8
15
 
9
16
  end
@@ -5,21 +5,22 @@ module Evil
5
5
  class Template < ActiveRecord::Base
6
6
  set_table_name :evil_templates
7
7
 
8
- validates_presence_of :route, :source
9
- validates_uniqueness_of :route
10
- validates_format_of :route, :with => /^((\/)|(((\/|\.):?[a-z0-9\_]+)+))$/
11
-
12
- after_save :reload_template_routes
13
- after_destroy :reload_template_routes
8
+ validates_presence_of :title, :source
9
+ validates_uniqueness_of :route, :if => lambda { |template| !(template.route.empty? || template.route.nil?) }
10
+ validates_format_of :route, :with => /^((\/)|(((\/|\.):?[a-z0-9\_]+)+))$/,
11
+ :allow_blank => true, :allow_nil => true
12
+ validate :liquid_syntax
14
13
 
15
14
  has_many :cached_pages
16
15
 
17
16
  named_scope :in_order, :order => 'position ASC'
18
17
 
19
- protected
18
+ private
20
19
 
21
- def reload_template_routes
22
- Evil::Routes.reload_template_routes
20
+ def liquid_syntax
21
+ Liquid::Template.parse(source)
22
+ rescue Liquid::SyntaxError => error
23
+ errors.add(:source, "has syntax error: #{error.message}")
23
24
  end
24
25
  end
25
26
 
data/lib/evil/models.rb CHANGED
@@ -1,17 +1,5 @@
1
1
  require 'activerecord'
2
2
  require 'evil/models/config_pair'
3
- require 'evil/models/plugin'
4
3
  require 'evil/models/template'
5
4
  require 'evil/models/whitelist'
6
5
 
7
- module Evil
8
- module Models
9
-
10
- def connect_to_database
11
- ActiveRecord::Base.establish_connection :adapter => 'sqlite3',
12
- :database => File.join(Evil.app_root, 'evil.db')
13
- end
14
-
15
- end
16
- end
17
-
@@ -0,0 +1,101 @@
1
+ require 'openid'
2
+ require 'openid/extensions/sreg'
3
+ require 'openid/store/memory'
4
+
5
+ module Evil
6
+ module OpenID
7
+ module Helpers
8
+
9
+ def openid_request?(open_id_param=params[:openid_url])
10
+ !!((open_id_param && !open_id_param.strip.empty?) || params[:openid_complete])
11
+ end
12
+
13
+ def openid_authenticate(options={}, &block)
14
+ open_id_param = options.delete(:open_id_param) || params[:openid_url]
15
+
16
+ unless params[:openid_complete]
17
+ begin_openid_authentication(open_id_param, options, &block)
18
+ else
19
+ complete_openid_authentication(&block)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def openid_consumer
26
+ @@openid_consumer ||= ::OpenID::Consumer.new session, ::OpenID::Store::Memory.new
27
+ end
28
+
29
+ def begin_openid_authentication(openid_url, options={})
30
+ fields = options[:sreg] || {}
31
+ immediate = (options[:immediate] === true)
32
+
33
+ request = openid_consumer.begin(openid_url)
34
+
35
+ add_sreg_fields(request, fields)
36
+
37
+ redirect openid_provider_url(request, immediate)
38
+
39
+ rescue ::OpenID::OpenIDError, Timeout::Error
40
+ yield :missing
41
+ end
42
+
43
+ def complete_openid_authentication
44
+ query_string_params = request.GET
45
+
46
+ begin
47
+ response = openid_consumer.complete(query_string_params, openid_return_to)
48
+ identity_url = response.endpoint.claimed_id
49
+
50
+ case response.status
51
+ when ::OpenID::Consumer::SUCCESS
52
+ yield :successful, identity_url, ::OpenID::SReg::Response.from_success_response(response)
53
+ when ::OpenID::Consumer::CANCEL
54
+ yield :cancelled, identity_url, nil
55
+ when ::OpenID::Consumer::FAILURE
56
+ yield :failed, identity_url, nil
57
+ when ::OpenID::Consumer::SETUP_NEEDED
58
+ # get around ruby openid 2.x bug
59
+ yield :setup_needed, identity_url, response.instance_variable_get(:@setup_url)
60
+ end
61
+ rescue Timeout::Error
62
+ yield :failed
63
+ end
64
+ end
65
+
66
+ def add_sreg_fields(request, fields)
67
+ if fields.is_a?(Array)
68
+ required, optional = fields, []
69
+ else
70
+ required = fields[:required] || []
71
+ optional = fields[:optional] || []
72
+ end
73
+
74
+ sreg = ::OpenID::SReg::Request.new
75
+
76
+ sreg.request_fields(required.collect { |f| f.to_s }, true) unless required.empty?
77
+ sreg.request_fields(optional.collect { |f| f.to_s }, false) unless optional.empty?
78
+
79
+ request.add_extension(sreg)
80
+ end
81
+
82
+ def openid_provider_url(request, immediate)
83
+ request.return_to_args['openid_complete'] = '1'
84
+ request.redirect_url(openid_trust_root, openid_return_to, immediate)
85
+ end
86
+
87
+ def openid_trust_root
88
+ @openid_trust_root ||= [
89
+ request.scheme, '://',
90
+ request.host,
91
+ (":#{request.port}" if request.port), "/"
92
+ ].compact.join
93
+ end
94
+
95
+ def openid_return_to
96
+ @openid_return_to ||= request.url
97
+ end
98
+
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,56 @@
1
+ module Evil
2
+ module Plugin
3
+ class Base
4
+ attr_reader :name, :configurator
5
+
6
+ def initialize(name, &block)
7
+ @name = name
8
+ @configurator = Configuration::Configurator.new
9
+ block.call(self)
10
+ end
11
+
12
+ def init
13
+ @setup_proc.call if @setup_proc
14
+ end
15
+
16
+ def description(desc=nil)
17
+ @description = desc if desc
18
+ @description
19
+ end
20
+
21
+ def setup(&block)
22
+ @setup_proc = block
23
+ end
24
+
25
+ def tag(name, &block)
26
+ tag = Tag.from(&block)
27
+ Liquid::Template.register_tag(name, tag)
28
+ end
29
+
30
+ def filter(fname, &block)
31
+ mod = Module.new do
32
+ define_method(fname, &block)
33
+ end
34
+
35
+ mod.module_eval "def self.name; \"_filter_#{fname}\"; end"
36
+
37
+ Liquid::Template.register_filter(mod)
38
+ end
39
+
40
+ def http
41
+ @http ||= Module.new do
42
+ include HTTParty
43
+ end
44
+ end
45
+
46
+ def configure
47
+ yield @configurator
48
+ end
49
+
50
+ def config
51
+ @config ||= Configuration::Config.new(self)
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,77 @@
1
+ module Evil
2
+ module Plugin
3
+ module Configuration
4
+
5
+ class ConfigField
6
+
7
+ attr_accessor :name, :type, :options
8
+
9
+ def initialize(type, name, options={})
10
+ @type, @name, @options = type, name, options
11
+ end
12
+
13
+ def label
14
+ options[:label] || name.to_s.capitalize
15
+ end
16
+
17
+ end
18
+
19
+ class Configurator
20
+
21
+ attr_reader :fields
22
+
23
+ def initialize
24
+ @fields = []
25
+ end
26
+
27
+ def text(field, options={})
28
+ @fields << ConfigField.new(:text, field, options)
29
+ end
30
+
31
+ def password(field, options={})
32
+ @fields << ConfigField.new(:password, field, options)
33
+ end
34
+
35
+ end
36
+
37
+ class Config
38
+ include Evil::Models
39
+
40
+ def initialize(plugin)
41
+ @plugin = plugin
42
+
43
+ load_config!
44
+ end
45
+
46
+ def [](val)
47
+ @values[val.to_sym]
48
+ end
49
+
50
+ def set(values)
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
54
+ end if values
55
+
56
+ load_config!
57
+ end
58
+
59
+ protected
60
+
61
+ def load_config!
62
+ pairs = Evil::Models::ConfigPair.find_all_by_plugin(@plugin.name)
63
+
64
+ if pairs
65
+ @values = pairs.inject(Hash.new('')) do |m, pair|
66
+ m[pair.key.to_sym] = pair.value; m
67
+ end
68
+ else
69
+ @values = Hash.new('')
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,15 @@
1
+ module Evil
2
+ module Plugin
3
+ module Environment
4
+ class << self
5
+ attr_reader :plugins
6
+
7
+ def plugin(name, &block)
8
+ @plugins ||= []
9
+ @plugins << Base.new(name, &block)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Evil
2
+ module Plugin
3
+
4
+ class Filesystem
5
+
6
+ def read_template_file(title)
7
+ if template = Evil::Models::Template.find_by_title(title)
8
+ template.source
9
+ else
10
+ raise FileSystemError, "No such template '#{title}'"
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+
18
+ end