### ### backmon.lib.updates ### import os import os.path import time import backup_monitoring.builtins from .exceptions import BackmonError from .locking import * # # Updates - Wrapper for directory receiving update outputs # class Updates(object): def __init__(self, logger, path): self.logger = logger self.path = path self.handles = {} # # open() - Open a handle to a monitored file # def open(self, filename, nolock=False, version=None): if version is not None: vext = '.%s' % (version) else: vext = '' path = os.path.join(self.path, '%s%s' % (filename, vext)) if os.path.isfile(path): if nolock or lock(path, retries=3, sleep=2): try: self.handles[filename] = open(path, 'r') return self.handles[filename] except IOError: self.logger.error('Could not open file %s!' % (path)) return None else: self.logger.error('Could not lock file %s!' % (path)) return None else: self.logger.error('File %s does not exist!' % (path)) return None # # close() - Close the handle to a monitored file # def close(self, filename, nolock=False, version=None): if version is not None: vext = '.%s' % (version) else: vext = '' path = os.path.join(self.path, '%s%s' % (filename, vext)) if os.path.isfile(path): if filename in self.handles: if hasattr(self.handles, 'close'): self.handles[filename].close() del self.handles[filename] if nolock or unlock(path): return True else: self.logger.error('Could not unlock file %s!' % (path)) return False else: self.logger.error('File %s is not open!' % (path)) return False else: self.logger.error('File %s does not exist!' % (path)) return False # # info() - Return the info object for a monitored feed # def info(self, feed, nolock=True, version=None): if version is not None: vext = '.%s' % (version) else: vext = '' inf_file = '%s.inf%s' % (feed, vext) txt_file = '%s.txt%s' % (feed, vext) file_path = os.path.join(self.path, txt_file) file = self.open(inf_file, nolock=nolock) if file is not None: info = {} for line in file: line = line.rstrip('\r\n') try: (key, value) = line.split('=') #self.logger.debug('%s=%s' % (key, value)) info[key] = value except: pass self.close(inf_file, nolock=nolock) if nolock or lock(file_path, retries=3, sleep=2): stat = os.stat(file_path) info['SIZE'] = float(stat.st_size) info['ATIME'] = float(stat.st_atime) info['MTIME'] = float(stat.st_mtime) info['CTIME'] = float(stat.st_ctime) if not nolock: unlock(file_path) else: info['SIZE'] = None info['ATIME'] = None info['MTIME'] = None info['CTIME'] = None return info else: return None # # read() - Return the contents of a monitored file # def read(self, filename): try: file = self.open(filename) data = file.read() self.close(filename) return data except Exception, e: raise BackmonError, e # # readlines() - Return all lines of a monitored file # def readlines(self, filename): try: file = self.open(filename) lines = file.readlines() self.close(filename) return lines except Exception, e: raise BackmonError, e # # feed() - Return a file-like object containing the current output of a feed # def feed(self, feed, storage='ram', version=None): if version is not None: vext = '.%s' % (version) else: vext = '' txt_file = '%s.txt%s' % (feed, vext) try: if storage == 'ram': return StringAsFile(self.read(txt_file)) else: raise BackmonError, 'no storage specified for Updates feed() method!' except Exception, e: raise BackmonError, e # # fopen() - Return an open file handle to a feed # def fopen(self, feed, nolock=True, version=None): txt_file = '%s.txt' % (feed) try: return self.open(txt_file, nolock, version) except Exception, e: raise # # fclose() - Close an open file handle to a feed # def fclose(self, feed, nolock=True, version=None): txt_file = '%s.txt' % (feed) try: return self.close(txt_file, nolock, version) except Exception, e: raise