1 | ###
|
---|
2 | ### backmon.lib.updates
|
---|
3 | ###
|
---|
4 | import os
|
---|
5 | import os.path
|
---|
6 | import time
|
---|
7 |
|
---|
8 | import backup_monitoring.builtins
|
---|
9 |
|
---|
10 | from .exceptions import BackmonError
|
---|
11 | from .locking import *
|
---|
12 |
|
---|
13 | #
|
---|
14 | # Updates - Wrapper for directory receiving update outputs
|
---|
15 | #
|
---|
16 | class Updates(object):
|
---|
17 |
|
---|
18 | def __init__(self, logger, path):
|
---|
19 |
|
---|
20 | self.logger = logger
|
---|
21 | self.path = path
|
---|
22 | self.handles = {}
|
---|
23 |
|
---|
24 | #
|
---|
25 | # open() - Open a handle to a monitored file
|
---|
26 | #
|
---|
27 | def open(self, filename, nolock=False, version=None):
|
---|
28 |
|
---|
29 | if version is not None:
|
---|
30 | vext = '.%s' % (version)
|
---|
31 | else:
|
---|
32 | vext = ''
|
---|
33 |
|
---|
34 | path = os.path.join(self.path, '%s%s' % (filename, vext))
|
---|
35 |
|
---|
36 | if os.path.isfile(path):
|
---|
37 |
|
---|
38 | if nolock or lock(path, retries=3, sleep=2):
|
---|
39 |
|
---|
40 | try:
|
---|
41 | self.handles[filename] = open(path, 'r')
|
---|
42 | return self.handles[filename]
|
---|
43 | except IOError:
|
---|
44 | self.logger.error('Could not open file %s!' % (path))
|
---|
45 | return None
|
---|
46 | else:
|
---|
47 | self.logger.error('Could not lock file %s!' % (path))
|
---|
48 | return None
|
---|
49 | else:
|
---|
50 | self.logger.error('File %s does not exist!' % (path))
|
---|
51 | return None
|
---|
52 |
|
---|
53 | #
|
---|
54 | # close() - Close the handle to a monitored file
|
---|
55 | #
|
---|
56 | def close(self, filename, nolock=False, version=None):
|
---|
57 |
|
---|
58 | if version is not None:
|
---|
59 | vext = '.%s' % (version)
|
---|
60 | else:
|
---|
61 | vext = ''
|
---|
62 |
|
---|
63 | path = os.path.join(self.path, '%s%s' % (filename, vext))
|
---|
64 |
|
---|
65 | if os.path.isfile(path):
|
---|
66 |
|
---|
67 | if filename in self.handles:
|
---|
68 |
|
---|
69 | if hasattr(self.handles, 'close'):
|
---|
70 | self.handles[filename].close()
|
---|
71 |
|
---|
72 | del self.handles[filename]
|
---|
73 |
|
---|
74 | if nolock or unlock(path):
|
---|
75 | return True
|
---|
76 | else:
|
---|
77 | self.logger.error('Could not unlock file %s!' % (path))
|
---|
78 | return False
|
---|
79 |
|
---|
80 | else:
|
---|
81 |
|
---|
82 | self.logger.error('File %s is not open!' % (path))
|
---|
83 | return False
|
---|
84 |
|
---|
85 | else:
|
---|
86 |
|
---|
87 | self.logger.error('File %s does not exist!' % (path))
|
---|
88 | return False
|
---|
89 |
|
---|
90 | #
|
---|
91 | # info() - Return the info object for a monitored feed
|
---|
92 | #
|
---|
93 | def info(self, feed, nolock=True, version=None):
|
---|
94 |
|
---|
95 | if version is not None:
|
---|
96 | vext = '.%s' % (version)
|
---|
97 | else:
|
---|
98 | vext = ''
|
---|
99 |
|
---|
100 | inf_file = '%s.inf%s' % (feed, vext)
|
---|
101 | txt_file = '%s.txt%s' % (feed, vext)
|
---|
102 |
|
---|
103 | file_path = os.path.join(self.path, txt_file)
|
---|
104 |
|
---|
105 | file = self.open(inf_file, nolock=nolock)
|
---|
106 |
|
---|
107 | if file is not None:
|
---|
108 |
|
---|
109 | info = {}
|
---|
110 |
|
---|
111 | for line in file:
|
---|
112 |
|
---|
113 | line = line.rstrip('\r\n')
|
---|
114 |
|
---|
115 | try:
|
---|
116 | (key, value) = line.split('=')
|
---|
117 | #self.logger.debug('%s=%s' % (key, value))
|
---|
118 | info[key] = value
|
---|
119 | except:
|
---|
120 | pass
|
---|
121 |
|
---|
122 | self.close(inf_file, nolock=nolock)
|
---|
123 |
|
---|
124 | if nolock or lock(file_path, retries=3, sleep=2):
|
---|
125 |
|
---|
126 | stat = os.stat(file_path)
|
---|
127 |
|
---|
128 | info['SIZE'] = float(stat.st_size)
|
---|
129 | info['ATIME'] = float(stat.st_atime)
|
---|
130 | info['MTIME'] = float(stat.st_mtime)
|
---|
131 | info['CTIME'] = float(stat.st_ctime)
|
---|
132 |
|
---|
133 | if not nolock:
|
---|
134 | unlock(file_path)
|
---|
135 |
|
---|
136 | else:
|
---|
137 |
|
---|
138 | info['SIZE'] = None
|
---|
139 | info['ATIME'] = None
|
---|
140 | info['MTIME'] = None
|
---|
141 | info['CTIME'] = None
|
---|
142 |
|
---|
143 | return info
|
---|
144 |
|
---|
145 | else:
|
---|
146 |
|
---|
147 | return None
|
---|
148 |
|
---|
149 | #
|
---|
150 | # read() - Return the contents of a monitored file
|
---|
151 | #
|
---|
152 | def read(self, filename):
|
---|
153 |
|
---|
154 | try:
|
---|
155 |
|
---|
156 | file = self.open(filename)
|
---|
157 | data = file.read()
|
---|
158 | self.close(filename)
|
---|
159 | return data
|
---|
160 |
|
---|
161 | except Exception, e:
|
---|
162 |
|
---|
163 | raise BackmonError, e
|
---|
164 |
|
---|
165 | #
|
---|
166 | # readlines() - Return all lines of a monitored file
|
---|
167 | #
|
---|
168 | def readlines(self, filename):
|
---|
169 |
|
---|
170 | try:
|
---|
171 |
|
---|
172 | file = self.open(filename)
|
---|
173 | lines = file.readlines()
|
---|
174 | self.close(filename)
|
---|
175 | return lines
|
---|
176 |
|
---|
177 | except Exception, e:
|
---|
178 |
|
---|
179 | raise BackmonError, e
|
---|
180 |
|
---|
181 | #
|
---|
182 | # feed() - Return a file-like object containing the current output of a feed
|
---|
183 | #
|
---|
184 | def feed(self, feed, storage='ram', version=None):
|
---|
185 |
|
---|
186 | if version is not None:
|
---|
187 | vext = '.%s' % (version)
|
---|
188 | else:
|
---|
189 | vext = ''
|
---|
190 |
|
---|
191 | txt_file = '%s.txt%s' % (feed, vext)
|
---|
192 |
|
---|
193 | try:
|
---|
194 |
|
---|
195 | if storage == 'ram':
|
---|
196 |
|
---|
197 | return StringAsFile(self.read(txt_file))
|
---|
198 |
|
---|
199 | else:
|
---|
200 |
|
---|
201 | raise BackmonError, 'no storage specified for Updates feed() method!'
|
---|
202 |
|
---|
203 | except Exception, e:
|
---|
204 |
|
---|
205 | raise BackmonError, e
|
---|
206 |
|
---|
207 |
|
---|
208 | #
|
---|
209 | # fopen() - Return an open file handle to a feed
|
---|
210 | #
|
---|
211 | def fopen(self, feed, nolock=True, version=None):
|
---|
212 |
|
---|
213 | txt_file = '%s.txt' % (feed)
|
---|
214 |
|
---|
215 | try:
|
---|
216 |
|
---|
217 | return self.open(txt_file, nolock, version)
|
---|
218 |
|
---|
219 | except Exception, e:
|
---|
220 |
|
---|
221 | raise
|
---|
222 |
|
---|
223 |
|
---|
224 | #
|
---|
225 | # fclose() - Close an open file handle to a feed
|
---|
226 | #
|
---|
227 | def fclose(self, feed, nolock=True, version=None):
|
---|
228 |
|
---|
229 | txt_file = '%s.txt' % (feed)
|
---|
230 |
|
---|
231 | try:
|
---|
232 |
|
---|
233 | return self.close(txt_file, nolock, version)
|
---|
234 |
|
---|
235 | except Exception, e:
|
---|
236 |
|
---|
237 | raise
|
---|
238 |
|
---|