rb.rotate 0.1.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/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +32 -0
- data/LICENSE.txt +20 -0
- data/README.md +81 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/bin/rb.rotate +12 -0
- data/lib/rb.rotate.rb +30 -0
- data/lib/rb.rotate/configuration.rb +312 -0
- data/lib/rb.rotate/directory.rb +201 -0
- data/lib/rb.rotate/dispatcher.rb +112 -0
- data/lib/rb.rotate/file.rb +174 -0
- data/lib/rb.rotate/hook.rb +135 -0
- data/lib/rb.rotate/install/defaults.yaml.initial +25 -0
- data/lib/rb.rotate/install/rotate.yaml.initial +349 -0
- data/lib/rb.rotate/log.rb +80 -0
- data/lib/rb.rotate/mail.rb +40 -0
- data/lib/rb.rotate/reader.rb +94 -0
- data/lib/rb.rotate/state.rb +211 -0
- data/lib/rb.rotate/state/archive.rb +109 -0
- data/lib/rb.rotate/state/file.rb +139 -0
- data/lib/rb.rotate/storage.rb +208 -0
- data/lib/rb.rotate/storage/entry.rb +120 -0
- data/lib/rb.rotate/storage/item.rb +415 -0
- data/rb.rotate.gemspec +85 -0
- metadata +153 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rb.rotate/configuration"
|
3
|
+
|
4
|
+
module RbRotate
|
5
|
+
|
6
|
+
##
|
7
|
+
# Logfile.
|
8
|
+
#
|
9
|
+
|
10
|
+
class Log
|
11
|
+
|
12
|
+
##
|
13
|
+
# Singletone instance.
|
14
|
+
#
|
15
|
+
|
16
|
+
@@self = nil
|
17
|
+
|
18
|
+
##
|
19
|
+
# Path to log.
|
20
|
+
#
|
21
|
+
|
22
|
+
@path
|
23
|
+
|
24
|
+
##
|
25
|
+
# Returns its singletone instance.
|
26
|
+
#
|
27
|
+
|
28
|
+
def self.get
|
29
|
+
if @@self.nil?
|
30
|
+
@@self = self::new(Configuration::get.paths[:"log file"])
|
31
|
+
end
|
32
|
+
|
33
|
+
return @@self
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Alias for #write.
|
38
|
+
#
|
39
|
+
|
40
|
+
def self.write(message, caller = nil)
|
41
|
+
self::get.write(message, caller)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Constructor.
|
46
|
+
#
|
47
|
+
|
48
|
+
def initialize(path)
|
49
|
+
@path = path
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Writes to log.
|
54
|
+
#
|
55
|
+
|
56
|
+
def write(message, caller = nil)
|
57
|
+
output = "[" << Time.now.strftime("%Y-%m-%d %H:%M:%S.%L") << "] "
|
58
|
+
if caller
|
59
|
+
output << caller.class.name << ": "
|
60
|
+
end
|
61
|
+
output << message << "\n"
|
62
|
+
|
63
|
+
::File.open(@path, "a") do |io|
|
64
|
+
io.write(output)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
class Object
|
73
|
+
##
|
74
|
+
# Logs an message.
|
75
|
+
#
|
76
|
+
|
77
|
+
def log(message)
|
78
|
+
RbRotate::Log::write(message, self)
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RbRotate
|
4
|
+
|
5
|
+
##
|
6
|
+
# Mail sender.
|
7
|
+
#
|
8
|
+
|
9
|
+
class Mail
|
10
|
+
|
11
|
+
##
|
12
|
+
# Pony class for delivering.
|
13
|
+
#
|
14
|
+
|
15
|
+
@@pony = nil
|
16
|
+
|
17
|
+
##
|
18
|
+
# Sends mail through Pony mail using specified parameters.
|
19
|
+
#
|
20
|
+
|
21
|
+
def self.send(parameters)
|
22
|
+
self::pony.mail(parameters)
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Returns the Pony class (includes if necessary).
|
27
|
+
#
|
28
|
+
|
29
|
+
def self.pony
|
30
|
+
if @@pony.nil?
|
31
|
+
require "pony"
|
32
|
+
@@pony = Pony
|
33
|
+
end
|
34
|
+
|
35
|
+
return @@pony
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rb.rotate/state"
|
3
|
+
|
4
|
+
module RbRotate
|
5
|
+
|
6
|
+
##
|
7
|
+
# Represents reader of some directory.
|
8
|
+
#
|
9
|
+
|
10
|
+
class Reader
|
11
|
+
|
12
|
+
##
|
13
|
+
# Directory for which reader has been created.
|
14
|
+
#
|
15
|
+
|
16
|
+
@directory
|
17
|
+
|
18
|
+
##
|
19
|
+
# Reads the directory. (Shortcut for non-static read.)
|
20
|
+
# Create new instance and call read.
|
21
|
+
#
|
22
|
+
|
23
|
+
def self.read(directory, options = { }, &block)
|
24
|
+
self::new(directory).read(options, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Constructor.
|
29
|
+
#
|
30
|
+
|
31
|
+
def initialize(directory)
|
32
|
+
@directory = directory
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Reads the directory content.
|
37
|
+
#
|
38
|
+
|
39
|
+
def read(options = { }, &block)
|
40
|
+
filter = options[:filter]
|
41
|
+
|
42
|
+
dirpath = @directory.path
|
43
|
+
Dir.open(dirpath) do |dir|
|
44
|
+
dir.each_entry do |item|
|
45
|
+
filepath = dirpath.dup << "/" << item
|
46
|
+
|
47
|
+
if (not @directory.configuration[:follow]) and (::File.symlink? filepath)
|
48
|
+
next
|
49
|
+
elsif (filter.nil? or (filter == :files)) and (::File.file? filepath)
|
50
|
+
emit_file filepath, &block
|
51
|
+
elsif (filter.nil? or (filter == :dirs)) and (item != ?.) and (item.to_sym != :"..") and (::File.directory? filepath)
|
52
|
+
emit_directory filepath, &block
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Returns the state file object.
|
60
|
+
#
|
61
|
+
|
62
|
+
def state
|
63
|
+
State::get
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
##
|
71
|
+
# Emits file.
|
72
|
+
#
|
73
|
+
|
74
|
+
def emit_file(filepath)
|
75
|
+
if not self.state.archive.has_file? filepath
|
76
|
+
yield File::new(filepath, @directory)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Emits directory.
|
82
|
+
#
|
83
|
+
|
84
|
+
def emit_directory(filepath)
|
85
|
+
if not self.state.archive.has_directory? filepath
|
86
|
+
yield Directory::new(filepath, @directory)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
@@ -0,0 +1,211 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "rb.rotate/configuration"
|
5
|
+
require "rb.rotate/state/archive"
|
6
|
+
require "rb.rotate/state/file"
|
7
|
+
|
8
|
+
module RbRotate
|
9
|
+
|
10
|
+
##
|
11
|
+
# Represents state file.
|
12
|
+
#
|
13
|
+
|
14
|
+
class State
|
15
|
+
|
16
|
+
##
|
17
|
+
# Holds self-instance as singleton.
|
18
|
+
#
|
19
|
+
|
20
|
+
@@self = nil
|
21
|
+
|
22
|
+
##
|
23
|
+
# Holds state data.
|
24
|
+
#
|
25
|
+
|
26
|
+
@data
|
27
|
+
|
28
|
+
##
|
29
|
+
# Holds path to state file.
|
30
|
+
#
|
31
|
+
|
32
|
+
@path
|
33
|
+
|
34
|
+
##
|
35
|
+
# Holds archive accessor instance.
|
36
|
+
#
|
37
|
+
|
38
|
+
@archive
|
39
|
+
|
40
|
+
##
|
41
|
+
# Constructor.
|
42
|
+
#
|
43
|
+
|
44
|
+
def initialize
|
45
|
+
@path = self.configuration.paths[:"state file"]
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Returns self instance.
|
50
|
+
#
|
51
|
+
|
52
|
+
def self.get
|
53
|
+
if @@self.nil?
|
54
|
+
@@self = self::new
|
55
|
+
end
|
56
|
+
|
57
|
+
return @@self
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Saves the file. (Shortcut to instance.)
|
62
|
+
#
|
63
|
+
|
64
|
+
def self.save!
|
65
|
+
self::get.save!
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Alias for #archive.
|
70
|
+
#
|
71
|
+
|
72
|
+
def self.archive
|
73
|
+
self::get.archive
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Alias for #files.
|
78
|
+
#
|
79
|
+
|
80
|
+
def self.files
|
81
|
+
self::get.files
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Alias for #each_file.
|
86
|
+
#
|
87
|
+
|
88
|
+
def self.each_file(&block)
|
89
|
+
self::get.each_file(&block)
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Returns data array.
|
94
|
+
#
|
95
|
+
|
96
|
+
def data
|
97
|
+
if @data.nil?
|
98
|
+
if not ::File.exists? @path
|
99
|
+
self.create!
|
100
|
+
else
|
101
|
+
@data = YAML.load(::File.read(@path))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
return @data
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Formats new storage.
|
110
|
+
#
|
111
|
+
|
112
|
+
def new
|
113
|
+
Hash[
|
114
|
+
:archive => {
|
115
|
+
:files => { },
|
116
|
+
:directories => { }
|
117
|
+
},
|
118
|
+
|
119
|
+
:files => { },
|
120
|
+
]
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Creates new storage.
|
125
|
+
#
|
126
|
+
|
127
|
+
def create!
|
128
|
+
@data = self.new
|
129
|
+
self.save!
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Saves the file.
|
134
|
+
#
|
135
|
+
|
136
|
+
def save!
|
137
|
+
self.compact!
|
138
|
+
::File.open(@path, "w") do |io|
|
139
|
+
io.write(self.data.to_yaml)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# Returns archive accessor instance.
|
145
|
+
#
|
146
|
+
|
147
|
+
def archive
|
148
|
+
if @archive.nil?
|
149
|
+
@archive = StateModule::Archive::new(self.data[:archive])
|
150
|
+
end
|
151
|
+
|
152
|
+
return @archive
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
# Returns files list.
|
157
|
+
#
|
158
|
+
|
159
|
+
def files
|
160
|
+
self.data[:files]
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# Compacts the file specifications.
|
165
|
+
# It removes all empty entries records.
|
166
|
+
#
|
167
|
+
|
168
|
+
def compact!
|
169
|
+
self.files.reject! do |key, value|
|
170
|
+
value.empty?
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
##
|
175
|
+
# Returns record for appropriate file.
|
176
|
+
#
|
177
|
+
|
178
|
+
def file(path)
|
179
|
+
data = self.files[path.to_sym]
|
180
|
+
|
181
|
+
if data.nil?
|
182
|
+
data = { }
|
183
|
+
self.files[path.to_sym] = data
|
184
|
+
end
|
185
|
+
|
186
|
+
StateModule::File::new(path, data)
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# Returns configuration object instance.
|
191
|
+
#
|
192
|
+
|
193
|
+
def configuration
|
194
|
+
Configuration::get
|
195
|
+
end
|
196
|
+
|
197
|
+
##
|
198
|
+
# Traverses through all files and emits path and
|
199
|
+
# StateModule::File objects.
|
200
|
+
#
|
201
|
+
|
202
|
+
def each_file
|
203
|
+
self.files.each_pair do |path, data|
|
204
|
+
if not data.empty?
|
205
|
+
yield path, StateModule::File::new(path, data)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RbRotate
|
4
|
+
module StateModule
|
5
|
+
|
6
|
+
##
|
7
|
+
# State file archive section.
|
8
|
+
#
|
9
|
+
|
10
|
+
class Archive
|
11
|
+
|
12
|
+
##
|
13
|
+
# Holds the archive data.
|
14
|
+
#
|
15
|
+
|
16
|
+
@data
|
17
|
+
|
18
|
+
##
|
19
|
+
# Constructor.
|
20
|
+
#
|
21
|
+
|
22
|
+
def initialize(data)
|
23
|
+
@data = data
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Returns file data.
|
28
|
+
#
|
29
|
+
|
30
|
+
def file(path)
|
31
|
+
self.files[path.to_sym]
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Returns files data.
|
36
|
+
#
|
37
|
+
|
38
|
+
def files
|
39
|
+
@data[:files]
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Indicates, file is in archive.
|
44
|
+
#
|
45
|
+
|
46
|
+
def has_file?(path)
|
47
|
+
@data[:files].has_key? path.to_sym
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Indicates, directory is in archive.
|
52
|
+
#
|
53
|
+
|
54
|
+
def has_directory?(path)
|
55
|
+
@data[:directories].has_key? path.to_sym
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Registers file.
|
60
|
+
#
|
61
|
+
|
62
|
+
def register_file(path, value = true)
|
63
|
+
self.register_item(:files, path, value)
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Unregisters file.
|
68
|
+
#
|
69
|
+
|
70
|
+
def unregister_file(path)
|
71
|
+
self.unregister_item(:files, path)
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
##
|
76
|
+
# Registers directory.
|
77
|
+
#
|
78
|
+
|
79
|
+
def register_directory(path, value = true)
|
80
|
+
self.register_item(:directories, path, value)
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Unregisters file.
|
85
|
+
#
|
86
|
+
|
87
|
+
def unregister_directory(path)
|
88
|
+
self.unregister_item(:directories, path)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Registers item.
|
93
|
+
#
|
94
|
+
|
95
|
+
def register_item(group, path, value = true)
|
96
|
+
@data[group][path.to_sym] = value
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Unregister item.
|
101
|
+
#
|
102
|
+
|
103
|
+
def unregister_item(group, path)
|
104
|
+
@data[group].delete(path.to_sym)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|