コード例 #1
0
ファイル: csw.py プロジェクト: LeadsPlus/ckanext-spatial
    def GetRecordById(self, req):
        resp = etree.Element(ntag("csw:GetRecordByIdResponse"), nsmap=namespaces)
        seen = set()
        for ident in req["id"]:
            doc = Session.query(HarvestObject) \
                    .join(Package) \
                    .join(HarvestJob).join(HarvestSource) \
                    .filter(HarvestSource.active==True) \
                    .filter(HarvestObject.guid==ident) \
                    .filter(HarvestObject.package!=None) \
                    .filter(Package.state==u'active') \
                    .order_by(HarvestObject.gathered.desc()) \
                    .limit(1).first()

            if doc is None:
                continue

            if 'MD_Metadata' in doc.content:
                try:
                    record = etree.parse(StringIO(doc.content.encode("utf-8")))
                    resp.append(record.getroot())
                except:
                    log.error("exception parsing document %s:\n%s", doc.id, traceback.format_exc())
                    raise

        data = self._render_xml(resp)
        log.info('GetRecordById response: %r', truncate(data, LOG_XML_LENGTH))
        return data
コード例 #2
0
def remove_public(item):
    '''
    Function to remove "Public - " from the labels for search facet.
    '''
    if item['display_name'].startswith('Public - '):
         item['display_name'] = item['display_name'][9:]
    return h.truncate(item['display_name'], 22)
コード例 #3
0
ファイル: csw.py プロジェクト: tum-gis/ckanext-spatial-sddi
    def GetRecordById(self, req):
        resp = etree.Element(ntag("csw:GetRecordByIdResponse"),
                             nsmap=namespaces)
        seen = set()
        for ident in req["id"]:
            doc = Session.query(HarvestObject) \
                    .join(Package) \
                    .join(HarvestJob).join(HarvestSource) \
                    .filter(HarvestSource.active==True) \
                    .filter(HarvestObject.guid==ident) \
                    .filter(HarvestObject.package!=None) \
                    .filter(Package.state==u'active') \
                    .order_by(HarvestObject.gathered.desc()) \
                    .limit(1).first()

            if doc is None:
                continue

            if 'MD_Metadata' in doc.content:
                try:
                    record = etree.parse(StringIO(doc.content.encode("utf-8")))
                    resp.append(record.getroot())
                except:
                    log.error("exception parsing document %s:\n%s", doc.id,
                              traceback.format_exc())
                    raise

        data = self._render_xml(resp)
        log.info('GetRecordById response: %r', truncate(data, LOG_XML_LENGTH))
        return data
コード例 #4
0
def govil_markdown_extract(package_id, text, extract_length=190):
    ''' return the plain text representation of markdown encoded text.  That
    is the texted without any html tags.  If extract_length is 0 then it
    will not be truncated.'''
    RE_MD_HTML_TAGS = re.compile('<[^><]*>')

    if not text:
        return ''
    plain = RE_MD_HTML_TAGS.sub('', markdown(text))
    if not extract_length or len(plain) < extract_length:
        return literal(plain)

    end_a_tag = '<a data-toggle="collapse"' + \
                  ' onclick="$(\'#short_pack_des_'+package_id+'\').hide()"' + \
                  ' href="#full_pack_des_' + package_id + '"' + \
                  ' role="button"'+ \
                  ' aria-expanded="false"'+ \
                  ' aria-controls="full_pack_des_' + package_id + '">...</a>'

    return literal(
        text_type(
            truncate(plain,
                     length=extract_length,
                     indicator=end_a_tag,
                     whole_word=True)))
コード例 #5
0
    def after_search(self, results, params):
        _org_cache = {}
        try:
            for item in results['search_facets']['type']['items']:
                item['display_name'] = toolkit._(item['display_name'])
        except KeyError:
            pass
        try:
            for item in results['search_facets']['member_countries']['items']:
                item[
                    'display_name'] = toolkit.h.spc_member_countries_facet_label(
                        item)
        except KeyError:
            pass

        is_popular_first = toolkit.asbool(
            params.get('extras', {}).get('ext_popular_first', False))

        for item in results['results']:
            if len(item) == 1:
                # it's shortened search, probably initiated by bulk download
                continue

            if item.get('id'):
                item['tracking_summary'] = (
                    model.TrackingSummary.get_for_package(item['id']))
                item['five_star_rating'] = spc_utils._get_stars_from_solr(
                    item['id'])
                if _package_is_native(item['id']):
                    item['isPartOf'] = 'pdh.pacificdatahub'
                else:
                    src_type = _get_isPartOf(item['id'])
                    if src_type:
                        item['isPartOf'] = src_type

            if item.get('name'):
                item['ga_view_count'] = spc_utils.ga_view_count(item['name'])
            item['short_notes'] = h.truncate(item.get('notes', ''))

            if item.get('organization'):
                org_name = item['organization']['name']
                try:
                    organization = _org_cache[org_name]
                except KeyError:
                    organization = h.get_organization(org_name)
                    _org_cache[org_name] = organization
                item['organization_image_url'] = organization.get(
                    'image_display_url') or h.url_for_static(
                        '/base/images/placeholder-organization.png',
                        qualified=True)

        if is_popular_first:
            results['results'].sort(key=lambda i: i.get('ga_view_count', 0),
                                    reverse=True)

        spc_utils.store_search_query(params)

        return results
コード例 #6
0
ファイル: csw.py プロジェクト: LeadsPlus/ckanext-spatial
    def GetRecords(self, req):
        resp = etree.Element(ntag("csw:GetRecordsResponse"), nsmap=namespaces)
        etree.SubElement(resp, ntag("csw:SearchStatus"), timestamp=datetime.utcnow().isoformat())

        cursor = Session.connection()

        q = Session.query(distinct(HarvestObject.guid)) \
                .join(Package) \
                .join(HarvestSource) \
                .filter(HarvestObject.current==True) \
                .filter(Package.state==u'active') \
                .filter(or_(HarvestSource.type=='gemini-single', \
                        HarvestSource.type=='gemini-waf', \
                        HarvestSource.type=='csw'))

        ### TODO Parse query instead of stupidly just returning whatever we like
        startPosition = req["startPosition"] if req["startPosition"] > 0 else 1
        maxRecords = req["maxRecords"] if req["maxRecords"] > 0 else 10
        rset = q.offset(startPosition-1).limit(maxRecords)

        total = q.count()
        attrs = {
            "numberOfRecordsMatched": total,
            "elementSet": req["elementSetName"], # we lie here. it's always really "full"
            }
        if req["resultType"] == "results":
            returned = rset.count()
            attrs["numberOfRecordsReturned"] = returned
            if (total-startPosition-1) > returned:
                attrs["nextRecord"] = startPosition + returned
            else:
                attrs["nextRecord"] = 0
        else:
            attrs["numberOfRecordsReturned"] = 0

        attrs = dict((k, unicode(v)) for k,v in attrs.items())
        results = etree.SubElement(resp, ntag("csw:SearchResults"), **attrs)

        if req["resultType"] == "results":
            for guid, in Session.execute(rset):
                doc = Session.query(HarvestObject) \
                        .join(Package) \
                        .filter(HarvestObject.guid==guid) \
                        .filter(HarvestObject.current==True) \
                        .filter(Package.state==u'active') \
                        .first()
                try:

                    record = etree.parse(StringIO(doc.content.encode("utf-8")))
                    results.append(record.getroot())
                except:
                    log.error("exception parsing document %s:\n%s", doc.id, traceback.format_exc())
                    raise

        data = self._render_xml(resp)
        log.info('GetRecords response: %r', truncate(data, LOG_XML_LENGTH))
        return data
コード例 #7
0
 def _test_expectation(self, action, users, entity_names, interfaces,
                       entity_types, expect_it_works):
     if isinstance(users, model.User):
         users = [users]
     if isinstance(entity_names, basestring):
         entity_names = [entity_names]
     if action == 'create' and 'package_relationship' not in entity_types:
         entity_names = [str(random.random() * 100000000).replace('.', '-')]
     if action in ('delete', 'purge'):
         entity_names = ['filled in later']
     for user in users:
         for entity_name in entity_names:
             for interface in interfaces:
                 test_func = {
                     'rest': self._test_via_api,
                     'wui': self._test_via_wui
                 }[interface]
                 for entity_type in entity_types:
                     if action in ('delete', 'purge'):
                         if entity_type != 'package_relationship':
                             entity_name = '%s_%s_%s' % (action, user.name,
                                                         interface)
                             entity_class = self.ENTITY_CLASS_MAP[
                                 entity_type]
                         else:
                             raise NotImplementedError
                         entity = entity_class.by_name(entity_name)
                         assert entity, 'Have not created %s to %s: %r' %\
                                (entity_type, action, entity_name)
                         entity_name = str(entity.id)
                     ok, diagnostics = test_func(action, user, entity_name,
                                                 entity_type)
                     if ok != expect_it_works:
                         msg = 'Should be able to %s %s %r as user %r on %r interface. Diagnostics: %r' \
                               if expect_it_works else \
                               'Should NOT be able to %s %s %r as user %r on %r interface. Diagnostics: %r'
                         raise Exception(
                             msg %
                             (action, entity_type, entity_name, user.name,
                              interface, truncate(repr(diagnostics), 1000)))
コード例 #8
0
ファイル: test_authz.py プロジェクト: Open-Source-GIS/ckan
 def _test_expectation(self, action, users, entity_names,
                       interfaces, entity_types,
                       expect_it_works):
     if isinstance(users, model.User):
         users = [users]
     if isinstance(entity_names, basestring):
         entity_names = [entity_names]
     if action == 'create' and 'package_relationship' not in entity_types:
         entity_names = [str(random.random()*100000000).replace('.', '-')]
     if action in ('delete', 'purge'):
         entity_names = ['filled in later']
     for user in users:
         for entity_name in entity_names:
             for interface in interfaces:
                 test_func = {'rest':self._test_via_api,
                              'wui':self._test_via_wui}[interface]
                 for entity_type in entity_types:
                     if action in ('delete', 'purge'):
                         if entity_type != 'package_relationship':
                             entity_name = '%s_%s_%s' % (action, user.name, interface)
                             entity_class = self.ENTITY_CLASS_MAP[entity_type]
                         else:
                             raise NotImplementedError
                         entity = entity_class.by_name(entity_name)
                         assert entity, 'Have not created %s to %s: %r' %\
                                (entity_type, action, entity_name)
                         entity_name = str(entity.id)
                     ok, diagnostics = test_func(action, user, entity_name, entity_type)
                     if ok != expect_it_works:
                         msg = 'Should be able to %s %s %r as user %r on %r interface. Diagnostics: %r' \
                               if expect_it_works else \
                               'Should NOT be able to %s %s %r as user %r on %r interface. Diagnostics: %r'
                         raise Exception(msg % (action, entity_type, entity_name, user.name, interface, truncate(repr(diagnostics), 1000)))
コード例 #9
0
ファイル: csw.py プロジェクト: LeadsPlus/ckanext-spatial
    def GetCapabilities(self, req):
        site = request.host_url + request.path
        caps = etree.Element(ntag("csw:Capabilities"), nsmap=namespaces)
        srvid = etree.SubElement(caps, ntag("ows:ServiceIdentification"))
        title = etree.SubElement(srvid, ntag("ows:Title"))
        title.text = unicode(config["cswservice.title"])
        abstract = etree.SubElement(srvid, ntag("ows:Abstract"))
        abstract.text = unicode(config["cswservice.abstract"])
        keywords = etree.SubElement(srvid, ntag("ows:Keywords"))
        for word in [w.strip() for w in config["cswservice.keywords"].split(",")]:
            if word == "": continue
            kw = etree.SubElement(keywords, ntag("ows:Keyword"))
            kw.text = unicode(word)
        kwtype = etree.SubElement(keywords, ntag("ows:Type"))
        kwtype.text = unicode(config["cswservice.keyword_type"])
        srvtype = etree.SubElement(srvid, ntag("ows:ServiceType"))
        srvtype.text = "CSW"
        srvver = etree.SubElement(srvid, ntag("ows:ServiceTypeVersion"))
        srvver.text = "2.0.2"
        ### ows:Fees, ows:AccessConstraints

        provider = etree.SubElement(caps, ntag("ows:ServiceProvider"))
        provname = etree.SubElement(provider, ntag("ows:ProviderName"))
        provname.text = unicode(config["cswservice.provider_name"])
        attrs = {
            ntag("xlink:href"): site
            }
        etree.SubElement(provider, ntag("ows:ProviderSite"), **attrs)

        contact = etree.SubElement(provider, ntag("ows:ServiceContact"))
        name = etree.SubElement(contact, ntag("ows:IndividualName"))
        name.text = unicode(config["cswservice.contact_name"])
        pos = etree.SubElement(contact, ntag("ows:PositionName"))
        pos.text = unicode(config["cswservice.contact_position"])
        cinfo = etree.SubElement(contact, ntag("ows:ContactInfo"))
        phone = etree.SubElement(cinfo, ntag("ows:Phone"))
        voice = etree.SubElement(phone, ntag("ows:Voice"))
        voice.text = unicode(config["cswservice.contact_voice"])
        fax = etree.SubElement(phone, ntag("ows:Fax"))
        fax.text = unicode(config["cswservice.contact_fax"])
        addr = etree.SubElement(cinfo, ntag("ows:Address"))
        dpoint = etree.SubElement(addr, ntag("ows:DeliveryPoint"))
        dpoint.text= unicode(config["cswservice.contact_address"])
        city = etree.SubElement(addr, ntag("ows:City"))
        city.text = unicode(config["cswservice.contact_city"])
        region = etree.SubElement(addr, ntag("ows:AdministrativeArea"))
        region.text = unicode(config["cswservice.contact_region"])
        pcode = etree.SubElement(addr, ntag("ows:PostalCode"))
        pcode.text = unicode(config["cswservice.contact_pcode"])
        country = etree.SubElement(addr, ntag("ows:Country"))
        country.text = unicode(config["cswservice.contact_country"])
        email = etree.SubElement(addr, ntag("ows:ElectronicMailAddress"))
        email.text = unicode(config["cswservice.contact_email"])
        hours = etree.SubElement(cinfo, ntag("ows:HoursOfService"))
        hours.text = unicode(config["cswservice.contact_hours"])
        instructions = etree.SubElement(cinfo, ntag("ows:ContactInstructions"))
        instructions.text = unicode(config["cswservice.contact_instructions"])
        role = etree.SubElement(contact, ntag("ows:Role"))
        role.text = unicode(config["cswservice.contact_role"])

        opmeta = etree.SubElement(caps, ntag("ows:OperationsMetadata"))

        op = etree.SubElement(opmeta, ntag("ows:Operation"), name="GetCapabilities")
        dcp = etree.SubElement(op, ntag("ows:DCP"))
        http = etree.SubElement(dcp, ntag("ows:HTTP"))
        attrs = { ntag("xlink:href"): site }
        etree.SubElement(http, ntag("ows:Get"), **attrs)
        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
        pe = etree.SubElement(post, ntag("ows:Constraint"), name="PostEncoding")
        val = etree.SubElement(pe, ntag("ows:Value"))
        val.text = "XML"

        op = etree.SubElement(opmeta, ntag("ows:Operation"), name="GetRecords")
        dcp = etree.SubElement(op, ntag("ows:DCP"))
        http = etree.SubElement(dcp, ntag("ows:HTTP"))
        attrs = { ntag("xlink:href"): site }
        etree.SubElement(http, ntag("ows:Get"), **attrs)
        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
        pe = etree.SubElement(post, ntag("ows:Constraint"), name="PostEncoding")
        val = etree.SubElement(pe, ntag("ows:Value"))
        val.text = "XML"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="resultType")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "results"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputFormat")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "application/xml"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputSchema")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "http://www.isotc211.org/2005/gmd"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="typeNames")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "gmd:MD_Metadata"

        op = etree.SubElement(opmeta, ntag("ows:Operation"), name="GetRecordById")
        dcp = etree.SubElement(op, ntag("ows:DCP"))
        http = etree.SubElement(dcp, ntag("ows:HTTP"))
        attrs = { ntag("xlink:href"): site }
        etree.SubElement(http, ntag("ows:Get"), **attrs)
        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
        pe = etree.SubElement(post, ntag("ows:Constraint"), name="PostEncoding")
        val = etree.SubElement(pe, ntag("ows:Value"))
        val.text = "XML"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="resultType")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "results"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputFormat")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "application/xml"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputSchema")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "http://www.isotc211.org/2005/gmd"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="typeNames")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "gmd:MD_Metadata"

#        op = etree.SubElement(opmeta, ntag("ows:Operation"), name="Harvest")
#        dcp = etree.SubElement(op, ntag("ows:DCP"))
#        http = etree.SubElement(dcp, ntag("ows:HTTP"))
#        attrs = { ntag("xlink:href"): site }
#        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
#        pe = etree.SubElement(post, ntag("ows:Constraint"), name="PostEncoding")
#        val = etree.SubElement(pe, ntag("ows:Value"))
#        val.text = "XML"
#        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputFormat")
#        val = etree.SubElement(param, ntag("ows:Value"))
#        val.text = "application/xml"
#        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputSchema")
#        val = etree.SubElement(param, ntag("ows:Value"))
#        val.text = "http://www.isotc211.org/2005/gmd"

        filcap = etree.SubElement(caps, ntag("ogc:Filter_Capabilities"))
        spacap = etree.SubElement(filcap, ntag("ogc:Spatial_Capabilities"))
        geomop = etree.SubElement(spacap, ntag("ogc:GeometryOperands"))
        spaceop = etree.SubElement(spacap, ntag("ogc:SpatialOperators"))

        scalcap = etree.SubElement(filcap, ntag("ogc:Scalar_Capabilities"))
        lop = etree.SubElement(scalcap, ntag("ogc:LogicalOperators"))
        cop = etree.SubElement(scalcap, ntag("ogc:ComparisonOperators"))

        idcap = etree.SubElement(filcap, ntag("ogc:Id_Capabilities"))
        eid = etree.SubElement(idcap, ntag("ogc:EID"))
        fid = etree.SubElement(idcap, ntag("ogc:FID"))

        data = self._render_xml(caps)
        log.info('GetCapabilities response: %r', truncate(data, LOG_XML_LENGTH))
        return data
コード例 #10
0
ファイル: csw.py プロジェクト: tum-gis/ckanext-spatial-sddi
    def GetRecords(self, req):
        resp = etree.Element(ntag("csw:GetRecordsResponse"), nsmap=namespaces)
        etree.SubElement(resp,
                         ntag("csw:SearchStatus"),
                         timestamp=datetime.utcnow().isoformat())

        cursor = Session.connection()

        q = Session.query(distinct(HarvestObject.guid)) \
                .join(Package) \
                .join(HarvestSource) \
                .filter(HarvestObject.current==True) \
                .filter(Package.state==u'active') \
                .filter(or_(HarvestSource.type=='gemini-single', \
                        HarvestSource.type=='gemini-waf', \
                        HarvestSource.type=='csw'))

        ### TODO Parse query instead of stupidly just returning whatever we like
        startPosition = req["startPosition"] if req["startPosition"] > 0 else 1
        maxRecords = req["maxRecords"] if req["maxRecords"] > 0 else 10
        rset = q.offset(startPosition - 1).limit(maxRecords)

        total = q.count()
        attrs = {
            "numberOfRecordsMatched": total,
            "elementSet":
            req["elementSetName"],  # we lie here. it's always really "full"
        }
        if req["resultType"] == "results":
            returned = rset.count()
            attrs["numberOfRecordsReturned"] = returned
            if (total - startPosition - 1) > returned:
                attrs["nextRecord"] = startPosition + returned
            else:
                attrs["nextRecord"] = 0
        else:
            attrs["numberOfRecordsReturned"] = 0

        attrs = dict((k, unicode(v)) for k, v in attrs.items())
        results = etree.SubElement(resp, ntag("csw:SearchResults"), **attrs)

        if req["resultType"] == "results":
            for guid, in Session.execute(rset):
                doc = Session.query(HarvestObject) \
                        .join(Package) \
                        .filter(HarvestObject.guid==guid) \
                        .filter(HarvestObject.current==True) \
                        .filter(Package.state==u'active') \
                        .first()
                try:

                    record = etree.parse(StringIO(doc.content.encode("utf-8")))
                    results.append(record.getroot())
                except:
                    log.error("exception parsing document %s:\n%s", doc.id,
                              traceback.format_exc())
                    raise

        data = self._render_xml(resp)
        log.info('GetRecords response: %r', truncate(data, LOG_XML_LENGTH))
        return data
コード例 #11
0
ファイル: csw.py プロジェクト: tum-gis/ckanext-spatial-sddi
    def GetCapabilities(self, req):
        site = request.host_url + request.path
        caps = etree.Element(ntag("csw:Capabilities"), nsmap=namespaces)
        srvid = etree.SubElement(caps, ntag("ows:ServiceIdentification"))
        title = etree.SubElement(srvid, ntag("ows:Title"))
        title.text = unicode(config["cswservice.title"])
        abstract = etree.SubElement(srvid, ntag("ows:Abstract"))
        abstract.text = unicode(config["cswservice.abstract"])
        keywords = etree.SubElement(srvid, ntag("ows:Keywords"))
        for word in [
                w.strip() for w in config["cswservice.keywords"].split(",")
        ]:
            if word == "": continue
            kw = etree.SubElement(keywords, ntag("ows:Keyword"))
            kw.text = unicode(word)
        kwtype = etree.SubElement(keywords, ntag("ows:Type"))
        kwtype.text = unicode(config["cswservice.keyword_type"])
        srvtype = etree.SubElement(srvid, ntag("ows:ServiceType"))
        srvtype.text = "CSW"
        srvver = etree.SubElement(srvid, ntag("ows:ServiceTypeVersion"))
        srvver.text = "2.0.2"
        ### ows:Fees, ows:AccessConstraints

        provider = etree.SubElement(caps, ntag("ows:ServiceProvider"))
        provname = etree.SubElement(provider, ntag("ows:ProviderName"))
        provname.text = unicode(config["cswservice.provider_name"])
        attrs = {ntag("xlink:href"): site}
        etree.SubElement(provider, ntag("ows:ProviderSite"), **attrs)

        contact = etree.SubElement(provider, ntag("ows:ServiceContact"))
        name = etree.SubElement(contact, ntag("ows:IndividualName"))
        name.text = unicode(config["cswservice.contact_name"])
        pos = etree.SubElement(contact, ntag("ows:PositionName"))
        pos.text = unicode(config["cswservice.contact_position"])
        cinfo = etree.SubElement(contact, ntag("ows:ContactInfo"))
        phone = etree.SubElement(cinfo, ntag("ows:Phone"))
        voice = etree.SubElement(phone, ntag("ows:Voice"))
        voice.text = unicode(config["cswservice.contact_voice"])
        fax = etree.SubElement(phone, ntag("ows:Fax"))
        fax.text = unicode(config["cswservice.contact_fax"])
        addr = etree.SubElement(cinfo, ntag("ows:Address"))
        dpoint = etree.SubElement(addr, ntag("ows:DeliveryPoint"))
        dpoint.text = unicode(config["cswservice.contact_address"])
        city = etree.SubElement(addr, ntag("ows:City"))
        city.text = unicode(config["cswservice.contact_city"])
        region = etree.SubElement(addr, ntag("ows:AdministrativeArea"))
        region.text = unicode(config["cswservice.contact_region"])
        pcode = etree.SubElement(addr, ntag("ows:PostalCode"))
        pcode.text = unicode(config["cswservice.contact_pcode"])
        country = etree.SubElement(addr, ntag("ows:Country"))
        country.text = unicode(config["cswservice.contact_country"])
        email = etree.SubElement(addr, ntag("ows:ElectronicMailAddress"))
        email.text = unicode(config["cswservice.contact_email"])
        hours = etree.SubElement(cinfo, ntag("ows:HoursOfService"))
        hours.text = unicode(config["cswservice.contact_hours"])
        instructions = etree.SubElement(cinfo, ntag("ows:ContactInstructions"))
        instructions.text = unicode(config["cswservice.contact_instructions"])
        role = etree.SubElement(contact, ntag("ows:Role"))
        role.text = unicode(config["cswservice.contact_role"])

        opmeta = etree.SubElement(caps, ntag("ows:OperationsMetadata"))

        op = etree.SubElement(opmeta,
                              ntag("ows:Operation"),
                              name="GetCapabilities")
        dcp = etree.SubElement(op, ntag("ows:DCP"))
        http = etree.SubElement(dcp, ntag("ows:HTTP"))
        attrs = {ntag("xlink:href"): site}
        etree.SubElement(http, ntag("ows:Get"), **attrs)
        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
        pe = etree.SubElement(post,
                              ntag("ows:Constraint"),
                              name="PostEncoding")
        val = etree.SubElement(pe, ntag("ows:Value"))
        val.text = "XML"

        op = etree.SubElement(opmeta, ntag("ows:Operation"), name="GetRecords")
        dcp = etree.SubElement(op, ntag("ows:DCP"))
        http = etree.SubElement(dcp, ntag("ows:HTTP"))
        attrs = {ntag("xlink:href"): site}
        etree.SubElement(http, ntag("ows:Get"), **attrs)
        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
        pe = etree.SubElement(post,
                              ntag("ows:Constraint"),
                              name="PostEncoding")
        val = etree.SubElement(pe, ntag("ows:Value"))
        val.text = "XML"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="resultType")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "results"
        param = etree.SubElement(op,
                                 ntag("ows:Parameter"),
                                 name="outputFormat")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "application/xml"
        param = etree.SubElement(op,
                                 ntag("ows:Parameter"),
                                 name="outputSchema")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "http://www.isotc211.org/2005/gmd"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="typeNames")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "gmd:MD_Metadata"

        op = etree.SubElement(opmeta,
                              ntag("ows:Operation"),
                              name="GetRecordById")
        dcp = etree.SubElement(op, ntag("ows:DCP"))
        http = etree.SubElement(dcp, ntag("ows:HTTP"))
        attrs = {ntag("xlink:href"): site}
        etree.SubElement(http, ntag("ows:Get"), **attrs)
        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
        pe = etree.SubElement(post,
                              ntag("ows:Constraint"),
                              name="PostEncoding")
        val = etree.SubElement(pe, ntag("ows:Value"))
        val.text = "XML"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="resultType")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "results"
        param = etree.SubElement(op,
                                 ntag("ows:Parameter"),
                                 name="outputFormat")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "application/xml"
        param = etree.SubElement(op,
                                 ntag("ows:Parameter"),
                                 name="outputSchema")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "http://www.isotc211.org/2005/gmd"
        param = etree.SubElement(op, ntag("ows:Parameter"), name="typeNames")
        val = etree.SubElement(param, ntag("ows:Value"))
        val.text = "gmd:MD_Metadata"

        #        op = etree.SubElement(opmeta, ntag("ows:Operation"), name="Harvest")
        #        dcp = etree.SubElement(op, ntag("ows:DCP"))
        #        http = etree.SubElement(dcp, ntag("ows:HTTP"))
        #        attrs = { ntag("xlink:href"): site }
        #        post = etree.SubElement(http, ntag("ows:Post"), **attrs)
        #        pe = etree.SubElement(post, ntag("ows:Constraint"), name="PostEncoding")
        #        val = etree.SubElement(pe, ntag("ows:Value"))
        #        val.text = "XML"
        #        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputFormat")
        #        val = etree.SubElement(param, ntag("ows:Value"))
        #        val.text = "application/xml"
        #        param = etree.SubElement(op, ntag("ows:Parameter"), name="outputSchema")
        #        val = etree.SubElement(param, ntag("ows:Value"))
        #        val.text = "http://www.isotc211.org/2005/gmd"

        filcap = etree.SubElement(caps, ntag("ogc:Filter_Capabilities"))
        spacap = etree.SubElement(filcap, ntag("ogc:Spatial_Capabilities"))
        geomop = etree.SubElement(spacap, ntag("ogc:GeometryOperands"))
        spaceop = etree.SubElement(spacap, ntag("ogc:SpatialOperators"))

        scalcap = etree.SubElement(filcap, ntag("ogc:Scalar_Capabilities"))
        lop = etree.SubElement(scalcap, ntag("ogc:LogicalOperators"))
        cop = etree.SubElement(scalcap, ntag("ogc:ComparisonOperators"))

        idcap = etree.SubElement(filcap, ntag("ogc:Id_Capabilities"))
        eid = etree.SubElement(idcap, ntag("ogc:EID"))
        fid = etree.SubElement(idcap, ntag("ogc:FID"))

        data = self._render_xml(caps)
        log.info('GetCapabilities response: %r',
                 truncate(data, LOG_XML_LENGTH))
        return data