danwrong-evil 0.1 → 0.1.1

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