cockpit 0.1.1 → 0.2.0
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/{MIT-LICENSE → MIT-LICENSE.markdown} +0 -0
- data/README.markdown +70 -47
- data/lib/cockpit.rb +1 -0
- data/lib/cockpit/core/definition.rb +187 -76
- data/lib/cockpit/core/global.rb +35 -0
- data/lib/cockpit/core/helpers.rb +12 -0
- data/lib/cockpit/core/include.rb +29 -74
- data/lib/cockpit/core/scope.rb +46 -0
- data/lib/cockpit/core/settings.rb +113 -74
- data/lib/cockpit/core/spec.rb +65 -0
- data/lib/cockpit/core/store.rb +34 -38
- data/lib/cockpit/stores/active_record.rb +128 -0
- data/lib/cockpit/stores/file_system.rb +11 -0
- data/lib/cockpit/stores/memory.rb +16 -0
- data/lib/cockpit/stores/mongo.rb +29 -0
- data/lib/cockpit/stores/redis.rb +11 -0
- metadata +16 -19
- data/Rakefile +0 -79
- data/lib/cockpit/core/definitions.rb +0 -55
- data/lib/cockpit/many/include.rb +0 -18
- data/lib/cockpit/many/settings.rb +0 -21
- data/lib/cockpit/moneta/active_record.rb +0 -120
- data/lib/cockpit/moneta/simple_active_record.rb +0 -93
- data/test/lib/database.rb +0 -22
- data/test/lib/user.rb +0 -10
- data/test/test_active_record.rb +0 -80
- data/test/test_helper.rb +0 -88
- data/test/test_mongo.rb +0 -82
- data/test/test_stores.rb +0 -125
@@ -1,55 +0,0 @@
|
|
1
|
-
module Cockpit
|
2
|
-
# settings have one direct definition and many child definitions
|
3
|
-
class Definitions < Hash
|
4
|
-
attr_accessor :name, :scope
|
5
|
-
|
6
|
-
def initialize(*args, &block)
|
7
|
-
define!(*args, &block)
|
8
|
-
end
|
9
|
-
|
10
|
-
def define!(*args, &block)
|
11
|
-
options = args.extract_options!
|
12
|
-
options[:store] ||= args.first
|
13
|
-
options.each do |k, v|
|
14
|
-
send("#{k}=", v) if respond_to?("#{k}=")
|
15
|
-
end
|
16
|
-
raise ArgumentError.new("pass a :name to Cockpit::Setting.define!") if self.name.blank?
|
17
|
-
if block_given?
|
18
|
-
self << Cockpit::Definition.define!(&block)
|
19
|
-
end
|
20
|
-
self
|
21
|
-
end
|
22
|
-
|
23
|
-
def <<(value)
|
24
|
-
([value] + self.values).flatten.uniq.each do |definition|
|
25
|
-
self.merge!(definition.keys)
|
26
|
-
end
|
27
|
-
self
|
28
|
-
end
|
29
|
-
|
30
|
-
def []=(key, value)
|
31
|
-
self << Cockpit::Definition.new(key, value) unless has_key?(key)
|
32
|
-
super(key.to_s, value)
|
33
|
-
end
|
34
|
-
|
35
|
-
def [](key)
|
36
|
-
super(key.to_s)
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_hash
|
40
|
-
keys.inject({}) do |hash, key|
|
41
|
-
hash[key] = self[key].value
|
42
|
-
hash
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def method_missing(method, *args, &block)
|
47
|
-
if has_key?(method)
|
48
|
-
self[method]
|
49
|
-
else
|
50
|
-
super(method, *args, &block)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
data/lib/cockpit/many/include.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Cockpit
|
2
|
-
module Include
|
3
|
-
module ActiveRecord
|
4
|
-
def self.included(base)
|
5
|
-
base.extend ClassMethods
|
6
|
-
base.send(:include, InstanceMethods)
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
module InstanceMethods
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Cockpit
|
2
|
-
module Many
|
3
|
-
class Settings
|
4
|
-
class << self
|
5
|
-
def define(&block)
|
6
|
-
DefinedBy::DSL(&block).each do |key, value, dsl_block|
|
7
|
-
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class Setting
|
14
|
-
attr_reader :definition
|
15
|
-
|
16
|
-
def method_name
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require "active_record"
|
3
|
-
rescue LoadError
|
4
|
-
puts "You need the activerecord gem in order to use the ActiveRecord moneta store"
|
5
|
-
exit
|
6
|
-
end
|
7
|
-
|
8
|
-
class Object
|
9
|
-
unless respond_to?(:symbolize_keys)
|
10
|
-
def symbolize_keys
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module Moneta
|
17
|
-
module Adapters
|
18
|
-
class ActiveRecord
|
19
|
-
class Store < ::ActiveRecord::Base
|
20
|
-
set_primary_key 'key'
|
21
|
-
set_table_name 'settings'
|
22
|
-
belongs_to :configurable, :polymorphic => true
|
23
|
-
|
24
|
-
def parsed_value
|
25
|
-
JSON.parse(value)['root']
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def initialize(options = {})
|
30
|
-
@options = options
|
31
|
-
@configurable = options[:record]
|
32
|
-
@cache = []
|
33
|
-
#Store.establish_connection(@options[:connection] || raise("Must specify :connection"))
|
34
|
-
Store.set_table_name(@options[:table] || 'settings')
|
35
|
-
end
|
36
|
-
|
37
|
-
module Implementation
|
38
|
-
def key?(key)
|
39
|
-
!!self[key]
|
40
|
-
end
|
41
|
-
|
42
|
-
def has_key?(key)
|
43
|
-
key?(key)
|
44
|
-
end
|
45
|
-
|
46
|
-
def [](key)
|
47
|
-
record = find_record(key)
|
48
|
-
record ? record.parsed_value : nil
|
49
|
-
end
|
50
|
-
|
51
|
-
def []=(key, value)
|
52
|
-
record = find_record(key)
|
53
|
-
attributes = {:value => {'root' => value}.to_json}.merge(configurable_attributes)
|
54
|
-
if record
|
55
|
-
record.update_attributes!(attributes)
|
56
|
-
else
|
57
|
-
store = Store.new(attributes)
|
58
|
-
store.key = key
|
59
|
-
store.save!
|
60
|
-
@cache << store
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def fetch(key, value = nil)
|
65
|
-
value ||= block_given? ? yield(key) : default # TODO: Shouldn't yield if key is present?
|
66
|
-
self[key] || value
|
67
|
-
end
|
68
|
-
|
69
|
-
def delete(key)
|
70
|
-
record = find_record(key)
|
71
|
-
if record
|
72
|
-
@cache.delete(record)
|
73
|
-
record.destroy
|
74
|
-
record.parsed_value
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def store(key, value, options = {})
|
79
|
-
self[key] = value
|
80
|
-
end
|
81
|
-
|
82
|
-
def clear
|
83
|
-
#Store.delete_all
|
84
|
-
end
|
85
|
-
|
86
|
-
private
|
87
|
-
def find_record(key)
|
88
|
-
if record = @cache.detect { |i| i.key == key }
|
89
|
-
record
|
90
|
-
else
|
91
|
-
@cache = Store.all(:conditions => configurable_attributes)
|
92
|
-
Store.find_by_key(key, :conditions => configurable_attributes) rescue nil
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def configurable_attributes
|
97
|
-
conditions = {}
|
98
|
-
if @configurable
|
99
|
-
conditions[:configurable_type] = @configurable.class.name
|
100
|
-
conditions[:configurable_id] = @configurable.id
|
101
|
-
else
|
102
|
-
conditions[:configurable_type] = nil
|
103
|
-
conditions[:configurable_id] = nil
|
104
|
-
end
|
105
|
-
conditions
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
# Unimplemented
|
111
|
-
module Expiration
|
112
|
-
def update_key(key, options)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
include Implementation
|
117
|
-
include Expiration
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require "active_record"
|
3
|
-
rescue LoadError
|
4
|
-
puts "You need the activerecord gem in order to use the ActiveRecord moneta store"
|
5
|
-
exit
|
6
|
-
end
|
7
|
-
|
8
|
-
class Object
|
9
|
-
unless respond_to?(:symbolize_keys)
|
10
|
-
def symbolize_keys
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module Moneta
|
17
|
-
module Adapters
|
18
|
-
class SimpleActiveRecord
|
19
|
-
class Store < ::ActiveRecord::Base
|
20
|
-
set_primary_key 'key'
|
21
|
-
set_table_name 'settings'
|
22
|
-
|
23
|
-
def parsed_value
|
24
|
-
JSON.parse(value)['root']
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def initialize(options = {})
|
29
|
-
@options = options
|
30
|
-
#Store.establish_connection(@options[:connection] || raise("Must specify :connection"))
|
31
|
-
Store.set_table_name(@options[:table] || 'settings')
|
32
|
-
end
|
33
|
-
|
34
|
-
module Implementation
|
35
|
-
def key?(key)
|
36
|
-
!!self[key]
|
37
|
-
end
|
38
|
-
|
39
|
-
def has_key?(key)
|
40
|
-
key?(key)
|
41
|
-
end
|
42
|
-
|
43
|
-
def [](key)
|
44
|
-
record = Store.find_by_key(key)
|
45
|
-
record ? record.parsed_value : nil
|
46
|
-
end
|
47
|
-
|
48
|
-
def []=(key, value)
|
49
|
-
record = Store.find_by_key(key)
|
50
|
-
if record
|
51
|
-
record.update_attributes!(:value => {'root' => value}.to_json)
|
52
|
-
else
|
53
|
-
store = Store.new
|
54
|
-
store.key = key
|
55
|
-
store.value = {'root' => value}.to_json
|
56
|
-
store.save!
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def fetch(key, value = nil)
|
61
|
-
value ||= block_given? ? yield(key) : default # TODO: Shouldn't yield if key is present?
|
62
|
-
self[key] || value
|
63
|
-
end
|
64
|
-
|
65
|
-
def delete(key)
|
66
|
-
record = Store.find_by_key(key)
|
67
|
-
if record
|
68
|
-
record.destroy
|
69
|
-
record.parsed_value
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def store(key, value, options = {})
|
74
|
-
self[key] = value
|
75
|
-
end
|
76
|
-
|
77
|
-
def clear
|
78
|
-
Store.delete_all
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
# Unimplemented
|
84
|
-
module Expiration
|
85
|
-
def update_key(key, options)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
include Implementation
|
90
|
-
include Expiration
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
data/test/lib/database.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
3
|
-
rescue ArgumentError
|
4
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
|
5
|
-
end
|
6
|
-
|
7
|
-
ActiveRecord::Base.configurations = true
|
8
|
-
|
9
|
-
ActiveRecord::Schema.define(:version => 1) do
|
10
|
-
|
11
|
-
create_table :settings, :force => true do |t|
|
12
|
-
t.string :key
|
13
|
-
t.string :value
|
14
|
-
t.string :context
|
15
|
-
t.string :configurable_type
|
16
|
-
t.integer :configurable_id
|
17
|
-
end
|
18
|
-
|
19
|
-
create_table :users, :force => true do |t|
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
data/test/lib/user.rb
DELETED
data/test/test_active_record.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
-
|
3
|
-
class ActiveRecordTest < ActiveSupport::TestCase
|
4
|
-
|
5
|
-
context "ActiveRecord" do
|
6
|
-
|
7
|
-
setup do
|
8
|
-
Cockpit :active_record do
|
9
|
-
site do
|
10
|
-
title "My Site"
|
11
|
-
time_zone lambda { "Hawaii" }
|
12
|
-
feed do
|
13
|
-
per_page 10
|
14
|
-
formats %w(rss atom)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
should "retrieve default values" do
|
21
|
-
assert_equal "My Site", Cockpit::Settings.default("site.title")
|
22
|
-
end
|
23
|
-
|
24
|
-
should "define values at runtime" do
|
25
|
-
Cockpit::Settings["site.title"] = "New Site"
|
26
|
-
assert_equal "New Site", Cockpit::Settings["site.title"]
|
27
|
-
end
|
28
|
-
|
29
|
-
should "use moneta" do
|
30
|
-
assert Cockpit::Settings.store
|
31
|
-
Cockpit::Settings["site.title"] = "Another Site"
|
32
|
-
assert_equal "Another Site", Cockpit::Settings.store["site.title"]
|
33
|
-
# puts Moneta::Adapters::ActiveRecord::Store.all.inspect
|
34
|
-
end
|
35
|
-
|
36
|
-
context "instance" do
|
37
|
-
setup do
|
38
|
-
@settings = Cockpit::Settings.new(:store => :active_record, :name => "site-cache", :scope => "default") do
|
39
|
-
site "a site"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
should "have an instance of setting" do
|
44
|
-
assert @settings
|
45
|
-
assert_equal "a site", @settings["site"]
|
46
|
-
class User < ::ActiveRecord::Base
|
47
|
-
cockpit :active_record do
|
48
|
-
author "Lance"
|
49
|
-
title do
|
50
|
-
last_name "Pollard"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
assert_equal "Lance", User.cockpit["author"]
|
55
|
-
assert_equal "Pollard", User.cockpit["title.last_name"]
|
56
|
-
|
57
|
-
user = User.new
|
58
|
-
assert_equal "Lance", user.cockpit["author"]
|
59
|
-
assert_equal "Pollard", user.cockpit["title.last_name"]
|
60
|
-
end
|
61
|
-
|
62
|
-
should "be able to assiociate Proc and hash" do
|
63
|
-
require 'tzinfo'
|
64
|
-
@settings = Cockpit :active_record do
|
65
|
-
site do
|
66
|
-
time_zones "MST", :options => Proc.new { TZInfo::Timezone.all.map(&:name) }
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
assert_equal TZInfo::Timezone.all.map(&:name), @settings.definition("site.time_zones")[:options].call
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
teardown do
|
75
|
-
Cockpit::Settings.clear
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
require "rubygems"
|
2
|
-
require "ruby-debug"
|
3
|
-
gem 'test-unit'
|
4
|
-
require "test/unit"
|
5
|
-
require 'active_support'
|
6
|
-
require 'active_support/test_case'
|
7
|
-
require 'active_record'
|
8
|
-
require 'active_record/fixtures'
|
9
|
-
require 'shoulda'
|
10
|
-
require 'shoulda/active_record'
|
11
|
-
|
12
|
-
require File.dirname(__FILE__) + '/lib/database'
|
13
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '/../lib/cockpit'))
|
14
|
-
require File.dirname(__FILE__) + '/lib/user'
|
15
|
-
|
16
|
-
class Object
|
17
|
-
include Cockpit
|
18
|
-
end
|
19
|
-
|
20
|
-
ActiveRecord::Base.class_eval do
|
21
|
-
def self.detonate
|
22
|
-
all.map(&:destroy)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
ActiveSupport::TestCase.class_eval do
|
27
|
-
|
28
|
-
def load_settings
|
29
|
-
Cockpit do
|
30
|
-
asset :title => "Asset (and related) Settings" do
|
31
|
-
thumb do
|
32
|
-
width 100, :tip => "Thumb's width"
|
33
|
-
height 100, :tip => "Thumb's height"
|
34
|
-
end
|
35
|
-
medium do
|
36
|
-
width 600, :tip => "Thumb's width"
|
37
|
-
height 250, :tip => "Thumb's height"
|
38
|
-
end
|
39
|
-
large do
|
40
|
-
width 600, :tip => "Large's width"
|
41
|
-
height 295, :tip => "Large's height"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
authentication :title => "Authentication Settings" do
|
45
|
-
use_open_id true
|
46
|
-
use_oauth true
|
47
|
-
end
|
48
|
-
front_page do
|
49
|
-
slideshow_tag "slideshow"
|
50
|
-
slideshow_effect "fade"
|
51
|
-
end
|
52
|
-
page do
|
53
|
-
per_page 10
|
54
|
-
feed_per_page 10
|
55
|
-
end
|
56
|
-
people do
|
57
|
-
show_avatars true
|
58
|
-
default_avatar "/images/missing-person.png"
|
59
|
-
end
|
60
|
-
site do
|
61
|
-
title "Martini"
|
62
|
-
tagline "Developer Friendly, Client Ready Blog with Rails 3"
|
63
|
-
keywords "Rails 3, Heroku, JQuery, HTML 5, Blog Engine, CSS3"
|
64
|
-
copyright "© 2010 Viatropos. All rights reserved."
|
65
|
-
timezones :value => lambda { TimeZone.first }, :options => lambda { TimeZone.all }
|
66
|
-
date_format "%m %d, %Y"
|
67
|
-
time_format "%H"
|
68
|
-
week_starts_on "Monday", :options => ["Monday", "Sunday", "Friday"]
|
69
|
-
language "en-US", :options => ["en-US", "de"]
|
70
|
-
touch_enabled true
|
71
|
-
touch_as_subdomain false
|
72
|
-
google_analytics ""
|
73
|
-
teasers :title => "Teasers" do
|
74
|
-
disable false
|
75
|
-
left 1, :title => "Left Teaser"
|
76
|
-
right 2
|
77
|
-
center 3
|
78
|
-
end
|
79
|
-
main_quote 1
|
80
|
-
end
|
81
|
-
social do
|
82
|
-
facebook "http://facebook.com/viatropos"
|
83
|
-
twitter "http://twitter.com/viatropos"
|
84
|
-
email "lancejpollard@gmail.com"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|