Loading cloudcontrol/server/repository.py 0 → 100644 +116 −0 Original line number Diff line number Diff line """ A repository class used to manage a file repository. """ import os from threading import Lock from hashlib import sha1 from cloudcontrol.server.db import SObject from cloudcontrol.common.tql.db.tag import StaticTag class RepositoryOperationError(Exception): """ Error while repository operation. """ class Repository(object): """ A class abstracting operations on a file repository. """ def __init__(self, logger, server, directory, role='file'): self.logger = logger self._server = server self._directory = directory self._lock = Lock() self._objects = {} # Mapping between file names and tql objects self._role = role # Load TQL objects of already existing files: for name in self.list(): obj_id = self._object_id(name) sha1_hash, content = self.load(name) tql_object = SObject(obj_id) tql_object.register(StaticTag('r', self._role)) tql_object.register(StaticTag('hash', sha1_hash)) tql_object.register(StaticTag('name', name)) tql_object.register(StaticTag('size', len(content))) self._objects[name] = tql_object self._server.db.register(tql_object) def _fullname(self, name): """ Return the file fullname depending to its name. """ return os.path.join(self._directory, name) def _object_id(self, name): """ Return the TQL object id of the file. """ return '%s-%s' % (self._role, name) def save(self, name, content): """ Save a file to the repository. """ fullname = self._fullname(name) self.logger.debug('Saving file %r to %s', name, fullname) try: with open(fullname, 'w') as ffile: ffile.write(content) except IOError as err: msg = 'Error while saving: %s' % err raise RepositoryOperationError(msg) else: obj_id = self._object_id(name) sha1_hash = sha1(content).hexdigest() if name in self._objects: tql_object = self._objects[name] tql_object['hash'].value = sha1_hash tql_object['size'].value = len(content) else: tql_object = SObject(obj_id) tql_object.register(StaticTag('r', self._role)) tql_object.register(StaticTag('hash', sha1_hash)) tql_object.register(StaticTag('name', name)) tql_object.register(StaticTag('size', len(content))) self._server.db.register(tql_object) self._objects[name] = tql_object return obj_id def load(self, name): """ Load a file from the repository and compute its sha1sum. :return: a tuple (sha1_hash, content) """ fullname = self._fullname(name) try: with open(fullname, 'r') as ffile: content = ffile.read() except IOError as err: msg = 'Error while saving: %s' % err raise RepositoryOperationError(msg) else: sha1_hash = sha1(content).hexdigest() self.logger.debug('Loaded plugin %r, hash = %s', name, sha1_hash) return sha1_hash, content def delete(self, name): """ Delete a file from the repository. :param name: name of the file to delete """ tql_object = self._objects.pop(name) if tql_object is None: raise RepositoryOperationError('Unknown object') self._server.db.unregister(tql_object) try: os.unlink(self._fullname(name)) except OSError as err: msg = 'Error while deleting: %s' % err raise RepositoryOperationError(msg) def list(self): """ List files of the repository. """ return os.listdir(self._directory) No newline at end of file Loading
cloudcontrol/server/repository.py 0 → 100644 +116 −0 Original line number Diff line number Diff line """ A repository class used to manage a file repository. """ import os from threading import Lock from hashlib import sha1 from cloudcontrol.server.db import SObject from cloudcontrol.common.tql.db.tag import StaticTag class RepositoryOperationError(Exception): """ Error while repository operation. """ class Repository(object): """ A class abstracting operations on a file repository. """ def __init__(self, logger, server, directory, role='file'): self.logger = logger self._server = server self._directory = directory self._lock = Lock() self._objects = {} # Mapping between file names and tql objects self._role = role # Load TQL objects of already existing files: for name in self.list(): obj_id = self._object_id(name) sha1_hash, content = self.load(name) tql_object = SObject(obj_id) tql_object.register(StaticTag('r', self._role)) tql_object.register(StaticTag('hash', sha1_hash)) tql_object.register(StaticTag('name', name)) tql_object.register(StaticTag('size', len(content))) self._objects[name] = tql_object self._server.db.register(tql_object) def _fullname(self, name): """ Return the file fullname depending to its name. """ return os.path.join(self._directory, name) def _object_id(self, name): """ Return the TQL object id of the file. """ return '%s-%s' % (self._role, name) def save(self, name, content): """ Save a file to the repository. """ fullname = self._fullname(name) self.logger.debug('Saving file %r to %s', name, fullname) try: with open(fullname, 'w') as ffile: ffile.write(content) except IOError as err: msg = 'Error while saving: %s' % err raise RepositoryOperationError(msg) else: obj_id = self._object_id(name) sha1_hash = sha1(content).hexdigest() if name in self._objects: tql_object = self._objects[name] tql_object['hash'].value = sha1_hash tql_object['size'].value = len(content) else: tql_object = SObject(obj_id) tql_object.register(StaticTag('r', self._role)) tql_object.register(StaticTag('hash', sha1_hash)) tql_object.register(StaticTag('name', name)) tql_object.register(StaticTag('size', len(content))) self._server.db.register(tql_object) self._objects[name] = tql_object return obj_id def load(self, name): """ Load a file from the repository and compute its sha1sum. :return: a tuple (sha1_hash, content) """ fullname = self._fullname(name) try: with open(fullname, 'r') as ffile: content = ffile.read() except IOError as err: msg = 'Error while saving: %s' % err raise RepositoryOperationError(msg) else: sha1_hash = sha1(content).hexdigest() self.logger.debug('Loaded plugin %r, hash = %s', name, sha1_hash) return sha1_hash, content def delete(self, name): """ Delete a file from the repository. :param name: name of the file to delete """ tql_object = self._objects.pop(name) if tql_object is None: raise RepositoryOperationError('Unknown object') self._server.db.unregister(tql_object) try: os.unlink(self._fullname(name)) except OSError as err: msg = 'Error while deleting: %s' % err raise RepositoryOperationError(msg) def list(self): """ List files of the repository. """ return os.listdir(self._directory) No newline at end of file