def __init__(self, env): self.env = env self.xmldb = XmlDbManager(env.db) self.index_catalog = XmlIndexCatalog(env.db, self.xmldb) self.index_catalog.env = env
class XmlCatalog(object): """ The catalog object. Use this class to manage all indexes and resources. """ def __init__(self, env): self.env = env self.xmldb = XmlDbManager(env.db) self.index_catalog = XmlIndexCatalog(env.db, self.xmldb) self.index_catalog.env = env def addResource(self, package_id, resourcetype_id, xml_data, uid=None, name=None): """ Add a new resource to the database. @param package_id: package id @param resourcetype_id: resourcetype id @param xml_data: xml data @param uid: user id of creator @param name: optional resource name, defaults to unique integer id @return: Resource object """ _, resourcetype = self.env.registry.objects_from_id(package_id, resourcetype_id) res = Resource(resourcetype, document=newXMLDocument(xml_data, uid=uid), name=name) # get xml_doc to ensure the document is parsed res.document.xml_doc self.validateResource(res) self.xmldb.addResource(res) self.index_catalog.indexResource(res) return res def renameResource(self, resource, new_name): """ Rename a given Resource object. """ self.xmldb.renameResource(resource, new_name) def modifyResource(self, resource, xml_data, uid=None): """ Modify the XML document of an already existing resource. In case of a version controlled resource a new revision is created. """ new_resource = Resource(resourcetype=resource.resourcetype, document=newXMLDocument(xml_data), name=resource.name) self.validateResource(new_resource) self.xmldb.modifyResource(resource, new_resource, uid) # we only keep indexes for the newest revision self.index_catalog.flushResource(resource) self.index_catalog.indexResource(new_resource) def deleteResource(self, resource=None, resource_id=None): """ Remove a resource from the database. """ if resource_id: resource = self.xmldb.getResource(id=resource_id) # create backup entry into the global trash folder if self.env.config.getbool('seishub', 'use_trash_folder', False): data = resource.document.data # ensure we return a UTF-8 encoded string not an Unicode object if isinstance(data, unicode): data = data.encode('utf-8') # set XML declaration inclusive UTF-8 encoding string if not data.startswith('<xml'): data = addXMLDeclaration(data, 'utf-8') path = os.path.join(self.env.getInstancePath(), 'data', 'trash', resource.package.package_id, resource.resourcetype.resourcetype_id) if not os.path.exists(path): os.makedirs(path) # add current datetime to filename to prevent overwriting resources # with the same filename (e.g. resource deleted/created several # times) filename = resource.name filename += datetime.datetime.now().strftime('__%Y%m%d%H%M%S') file = os.path.join(path, filename) try: fp = open(file, 'wb') fp.write(data) fp.close() except: pass # remove indexed data: self.index_catalog.flushResource(resource) res = self.xmldb.deleteResource(resource) if not res: msg = "Error deleting a resource: No resource was found with " + \ "the given parameters." raise NotFoundError(msg) return res def deleteAllResources(self, package_id, resourcetype_id=None): """ Remove all resources of specified package_id and resourcetype_id. """ return self.xmldb.deleteAllResources(package_id, resourcetype_id) def getResource(self, package_id=None, resourcetype_id=None, name=None, revision=None, document_id=None, id=None): """ Get a specific resource from the database. @param package_id: resourcetype id @param: resourcetype_id: package id @param name: Name of the resource @param revision: revision of related document (if no revision is given, newest revision is used, to retrieve all revisions of a document use getRevisions() """ return self.xmldb.getResource(package_id=package_id, resourcetype_id=resourcetype_id, name=name, revision=revision, document_id=document_id, id=id) def getRevisions(self, package_id, resourcetype_id, name): """ Get all revisions of the specified resource. The Resource instance returned will contain a list of documents sorted by revision (accessible as usual via Resource.document). Note: In case a resource does not provide multiple revisions, this is the same as a call to XmlCatalog.getResource(...). @param package_id: package id @param resourcetype_id: resourcetype id @param name: name of the resource @return: Resource object """ return self.xmldb.getRevisions(package_id, resourcetype_id, name) def getAllResources(self, package_id=None, resourcetype_id=None): """ Get a list of resources for specified package and resourcetype. """ return self.xmldb.getAllResources(package_id, resourcetype_id) # # def revertResource(self, package_id, resourcetype_id, name, revision): # """ # Reverts the specified revision for the given resource. # # All revisions newer than the specified one will be removed. # """ # return self.xmldb.revertResource(package_id, resourcetype_id, name, # revision) def validateResource(self, resource): """ Do a schema validation of a given resource. This validates against all schemas of the corresponding resourcetype. """ pid = resource.package.package_id rid = resource.resourcetype.resourcetype_id schemas = self.env.registry.schemas.get(pid, rid) for schema in schemas: try: schema.validate(resource) except Exception, e: msg = "Resource-validation against schema '%s' failed. (%s)" raise InvalidObjectError(msg % (str(schema.getResource().name), str(e)))