configural 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+ #--
2
+ #
3
+ # This file is one part of:
4
+ #
5
+ # Configural - Easy configuration file management
6
+ #
7
+ # Copyright (c) 2011 John Croisant
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ #++
29
+
30
+
31
+ module Configural
32
+
33
+ autoload :App, 'configural/app'
34
+ autoload :User, 'configural/user'
35
+ autoload :Config, 'configural/config'
36
+ autoload :Data, 'configural/data'
37
+ autoload :Cache, 'configural/data'
38
+ autoload :Platform, 'configural/platform'
39
+ autoload :Autosave, 'configural/autosave'
40
+
41
+ end
@@ -0,0 +1,97 @@
1
+ #--
2
+ #
3
+ # This file is one part of:
4
+ #
5
+ # Configural - Easy configuration file management
6
+ #
7
+ # Copyright (c) 2011 John Croisant
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ #++
29
+
30
+
31
+ module Configural
32
+
33
+ class App
34
+ attr_accessor :name, :path
35
+ attr_writer :config_path, :cache_path, :data_path
36
+ attr_reader :user
37
+
38
+ def initialize( name )
39
+ @name = name
40
+ @user = Configural::User.new(self)
41
+ end
42
+
43
+
44
+ def cache
45
+ @cache ||=
46
+ begin
47
+ unless @cache_path
48
+ raise 'you must set cache_path or path first'
49
+ end
50
+ Configural::Cache.new(self)
51
+ end
52
+ end
53
+
54
+ def cache_path
55
+ @cache_path || (@path and File.join(@path, 'cache'))
56
+ end
57
+
58
+
59
+ def config
60
+ @config ||=
61
+ begin
62
+ unless @config_path
63
+ raise 'you must set config_path or path first'
64
+ end
65
+ Configural::Config.new(self)
66
+ end
67
+ end
68
+
69
+ def config_path
70
+ @config_path || (@path and File.join(@path, 'config'))
71
+ end
72
+
73
+
74
+ def data
75
+ @data ||=
76
+ begin
77
+ unless @data_path
78
+ raise 'you must set data_path or path first'
79
+ end
80
+ Configural::Data.new(self)
81
+ end
82
+ end
83
+
84
+ def data_path
85
+ @data_path || (@path and File.join(@path, 'data'))
86
+ end
87
+
88
+
89
+ def save_all
90
+ @config.save_all if @config
91
+ @user.save_all if @user
92
+ self
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,100 @@
1
+ #--
2
+ #
3
+ # This file is one part of:
4
+ #
5
+ # Configural - Easy configuration file management
6
+ #
7
+ # Copyright (c) 2011 John Croisant
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ #++
29
+
30
+
31
+ module Configural
32
+
33
+ class Autosave
34
+
35
+ def self.instance
36
+ @instance ||= new()
37
+ end
38
+
39
+ # Shorthand for Autosave.instance.register
40
+ def self.register(*args)
41
+ instance.register(*args)
42
+ end
43
+
44
+ # Shorthand for Autosave.instance.unregister
45
+ def self.unregister(*args)
46
+ instance.unregister(*args)
47
+ end
48
+
49
+
50
+ def initialize
51
+ @weakrefs = {}
52
+ @enabled = true
53
+ at_exit{ self.save_all }
54
+ end
55
+
56
+
57
+ def register(object, method=:save)
58
+ require 'weakref'
59
+ weakref = WeakRef.new(object)
60
+ @weakrefs[weakref] = method
61
+ self
62
+ end
63
+
64
+ def unregister(object)
65
+ @weakrefs.delete_if{ |k,v| k.__id__ == object.object_id }
66
+ self
67
+ end
68
+
69
+ def unregister_all
70
+ @weakrefs = {}
71
+ self
72
+ end
73
+
74
+
75
+ attr_reader :enabled
76
+ alias :enabled? :enabled
77
+
78
+ def enable
79
+ @enabled = true
80
+ self
81
+ end
82
+
83
+ def disable
84
+ @enabled = false
85
+ self
86
+ end
87
+
88
+
89
+ def save_all
90
+ return self unless @enabled
91
+ @weakrefs.each do |weakref, method|
92
+ if weakref.weakref_alive? and weakref.respond_to?(method)
93
+ weakref.send(method)
94
+ end
95
+ end
96
+ self
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,93 @@
1
+ #--
2
+ #
3
+ # This file is one part of:
4
+ #
5
+ # Configural - Easy configuration file management
6
+ #
7
+ # Copyright (c) 2011 John Croisant
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ #++
29
+
30
+
31
+ module Configural
32
+
33
+ class Config
34
+
35
+ attr_accessor :owner, :options
36
+
37
+ def initialize( owner )
38
+ @owner = owner
39
+ @files = {}
40
+ @options = {
41
+ :default_format => 'yaml',
42
+ :lazy_loading => false,
43
+ }
44
+ end
45
+
46
+ def path
47
+ @owner.config_path
48
+ end
49
+
50
+ def [](name)
51
+ @files[name.to_s] ||= make_file(name.to_s)
52
+ end
53
+
54
+ def []=(name, value)
55
+ @files[name.to_s] = value
56
+ end
57
+
58
+ def save_all
59
+ @files.each_value{ |file| file.save }
60
+ self
61
+ end
62
+
63
+ private
64
+
65
+ def make_file(name)
66
+ if File.extname(name).empty?
67
+ # No file extension, so use the default format.
68
+ format = FileBase.get_format_by_name(@options[:default_format])
69
+ # Check all possible extensions, choose the first file that
70
+ # exists, or use the first file extension if no files exist.
71
+ paths = format.extnames.collect{ |extname|
72
+ File.join( self.path, name ) + extname
73
+ }
74
+ path = paths.find{ |p| File.exists?(p) } || paths.first
75
+ else
76
+ # Has a file extension, so try to find a matching format.
77
+ format = FileBase.get_format_by_extname(File.extname(name))
78
+ # Just use the name with already-specified extension.
79
+ path = File.join(self.path, name)
80
+ end
81
+ format.new( path, @options )
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+
89
+ require 'configural/config/file_base'
90
+ require 'configural/config/json_file'
91
+ require 'configural/config/plist_file'
92
+ require 'configural/config/sdl_file'
93
+ require 'configural/config/yaml_file'
@@ -0,0 +1,161 @@
1
+ #--
2
+ #
3
+ # This file is one part of:
4
+ #
5
+ # Configural - Easy configuration file management
6
+ #
7
+ # Copyright (c) 2011 John Croisant
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ #++
29
+
30
+
31
+ module Configural
32
+
33
+ # Base class for abstracting configuration file access. You
34
+ # shouldn't use this class directly. Use one of the subclasses (e.g.
35
+ # YAMLFile) instead.
36
+ #
37
+ class Config::FileBase
38
+
39
+ def self.inherited(subclass)
40
+ @subclasses ||= []
41
+ @subclasses << subclass
42
+ end
43
+
44
+
45
+ def self.get_format_by_name( format )
46
+ @subclasses.reverse.find { |subclass|
47
+ subclass.format == format
48
+ } or raise "Unrecognized file format: #{format}"
49
+ end
50
+
51
+ def self.get_format_by_extname( extname )
52
+ @subclasses.reverse.find { |subclass|
53
+ subclass.extnames.include?(extname)
54
+ } or raise "Unrecognized file extension: #{extname}"
55
+ end
56
+
57
+
58
+ def self.format
59
+ raise 'Method not implemented for base class.'
60
+ end
61
+
62
+ def self.extnames
63
+ raise 'Method not implemented for base class.'
64
+ end
65
+
66
+
67
+ require 'enumerator'
68
+ include Enumerable
69
+
70
+ attr_reader :path
71
+
72
+ def initialize( path, options )
73
+ @path = path
74
+ @options = options
75
+ @data = {}
76
+ @loaded = false
77
+ load unless @options[:lazy_loading]
78
+ end
79
+
80
+
81
+ def clear
82
+ @data = {}
83
+ @loaded = true
84
+ self
85
+ end
86
+
87
+ def close
88
+ @data = {}
89
+ @loaded = false
90
+ self
91
+ end
92
+
93
+ def delete
94
+ File.rm(path, :force => true)
95
+ self
96
+ end
97
+
98
+ def exists?
99
+ File.exists?(path)
100
+ end
101
+ alias :exist? :exists?
102
+
103
+ def each(&block)
104
+ load unless @loaded
105
+ @data.each(&block)
106
+ end
107
+
108
+ def keys
109
+ load unless @loaded
110
+ @data.keys
111
+ end
112
+
113
+ def [](key)
114
+ load unless @loaded
115
+ @data[key.to_s]
116
+ end
117
+
118
+ def []=(key, value)
119
+ load unless @loaded
120
+ @data[key.to_s] = value
121
+ end
122
+
123
+ def to_hash
124
+ load unless @loaded
125
+ @data.dup
126
+ end
127
+
128
+ def load
129
+ load! unless @loaded
130
+ self
131
+ end
132
+
133
+ def load!
134
+ _load
135
+ @loaded = true
136
+ self
137
+ end
138
+
139
+ def save
140
+ _save unless not @loaded
141
+ self
142
+ end
143
+
144
+ def save!
145
+ _save
146
+ self
147
+ end
148
+
149
+ private
150
+
151
+ def _load
152
+ raise 'Method not implemented for base class.'
153
+ end
154
+
155
+ def _save
156
+ raise 'Method not implemented for base class.'
157
+ end
158
+
159
+ end
160
+
161
+ end