def test_olac_list(self): from clld.web.views.olac import OlacConfig assert self.with_params( verb='ListIdentifiers', metadataPrefix='olac').findall('header') OlacConfig() id_ = self.with_params(verb='Identify').findone( '{http://www.openarchives.org/OAI/2.0/oai-identifier}sampleIdentifier').text assert self.with_params( verb='GetRecord', metadataPrefix='olac', identifier=id_).findone('record') assert self.with_params(verb='GetRecord', metadataPrefix='olac').error assert self.with_params( verb='GetRecord', metadataPrefix='ol', identifier=id_).error assert self.with_params( verb='GetRecord', metadataPrefix='olac', identifier=id_ + '123').error assert self.with_params( verb='ListIdentifiers', resumptionToken='tr', metadataPrefix='olac').error assert self.with_params( verb='ListIdentifiers', resumptionToken='tr', o='x').error assert self.with_params(verb='ListIdentifiers').error assert self.with_params( verb='ListIdentifiers', metadataPrefix='olac', set='x').error assert self.with_params(verb='ListIdentifiers', resumptionToken='tr').error assert not self.with_params( verb='ListIdentifiers', resumptionToken='0f2000-01-01u2222-01-01').error assert not self.with_params(verb='ListIdentifiers', resumptionToken='100').error assert self.with_params(verb='ListIdentifiers', resumptionToken='200').error assert self.with_params( verb='ListIdentifiers', resumptionToken='100f2000-01-01u2000-01-01').error
def description(self, req): res = OlacConfig.description(self, req) res['institution'] = Institution( 'Max Planck Institute for the Science of Human History', 'http://shh.mpg.de', 'Jena, Germany') return res
def description(self, req): res = OlacConfig.description(self, req) res['institution'] = Institution( 'Leiden University Centre for Linguistics', 'https://www.universiteitleiden.nl/en/humanities/leiden-university-centre-for-linguistics', 'Leiden, The Netherlands') return res
def test_olac_config(): from clld.web.views.olac import OlacConfig OlacConfig()
def includeme(config): """Upgrading: - register utilities "by hand", after config.include('clld.web.app') - add routes by hand (and remove these from the **kw passed to Configurator) :param config: :return: """ # # now we exploit the default package layout as created via the CLLD scaffold: # # note: the following exploits the import time side effect of modifying the webassets # environment! root_package = config.root_package.__name__ pkg_dir = Path(config.root_package.__file__).parent.resolve() maybe_import('%s.assets' % root_package, pkg_dir=pkg_dir) json_renderer = JSON() json_renderer.add_adapter(datetime.datetime, lambda obj, req: obj.isoformat()) json_renderer.add_adapter(datetime.date, lambda obj, req: obj.isoformat()) config.add_renderer('json', json_renderer) jsonp_renderer = JSONP(param_name='callback') jsonp_renderer.add_adapter(datetime.datetime, lambda obj, req: obj.isoformat()) jsonp_renderer.add_adapter(datetime.date, lambda obj, req: obj.isoformat()) config.add_renderer('jsonp', jsonp_renderer) config.set_request_factory(ClldRequest) config.registry.registerUtility(CtxFactoryQuery(), interfaces.ICtxFactoryQuery) config.registry.registerUtility(OlacConfig(), interfaces.IOlacConfig) config.registry.registerUtility(CldfConfig(), interfaces.ICldfConfig) # initialize the db connection engine = engine_from_config(config.registry.settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.bind = engine try: git_tag = git_describe(Path(pkg_dir).parent) except ValueError: # pragma: no cover git_tag = None config.add_settings({ 'pyramid.default_locale_name': 'en', 'clld.pkg': root_package, 'clld.git_tag': git_tag, 'clld.parameters': {} }) if 'clld.files' in config.registry.settings: # deployment-specific location of static data files abspath = Path(config.registry.settings['clld.files']).resolve() config.add_settings({'clld.files': abspath}) config.add_static_view('files', str(abspath)) # event subscribers: config.add_subscriber(add_localizer, events.NewRequest) config.add_subscriber(init_map, events.ContextFound) config.add_subscriber( partial(add_renderer_globals, maybe_import('%s.util' % root_package, pkg_dir=pkg_dir)), events.BeforeRender) # # make it easy to register custom functionality # for name, func in { 'register_utility': register_utility, 'register_datatable': partial(register_cls, interfaces.IDataTable), 'register_map': partial(register_cls, interfaces.IMap), 'register_menu': register_menu, 'register_resource': register_resource, 'register_adapter': register_adapter, 'register_adapters': register_adapters, 'register_download': register_download, 'register_staticresource': register_staticresource, 'add_route_and_view': add_route_and_view, 'add_settings_from_file': add_settings_from_file, 'add_301': add_301, 'add_410': add_410, 'add_page': add_page, 'register_resource_routes_and_views': register_resource_routes_and_views, }.items(): config.add_directive(name, func) # # routes and views # config.add_static_view('clld-static', 'clld:web/static') config.add_static_view('static', '%s:static' % root_package) config.add_route_and_view('_js', '/_js', js, http_cache=3600) # add some maintenance hatches config.add_route_and_view('_raise', '/_raise', _raise) config.add_route_and_view('_ping', '/_ping', _ping, renderer='json') # sitemap support: config.add_route_and_view('robots', '/robots.txt', robots) config.add_route_and_view('sitemapindex', '/sitemap.xml', sitemapindex) config.add_route_and_view('sitemap', '/sitemap.{rsc}.{n}.xml', sitemap) config.add_route('resourcemap', '/resourcemap.json') config.add_view(resourcemap, route_name='resourcemap', renderer='jsonp') config.add_route_and_view('select_combination', '/_select_combination', select_combination) config.add_route_and_view('unapi', '/unapi', unapi) config.add_route_and_view('olac', '/olac', olac) config.add_settings_from_file(pkg_dir.joinpath('appconf.ini')) if not config.registry.settings.get('mako.directories'): config.add_settings({'mako.directories': ['clld:web/templates']}) for rsc in RESOURCES: config.register_resource_routes_and_views(rsc) config.register_datatable( rsc.plural, getattr(datatables, rsc.plural.capitalize(), DataTable)) register_resource_adapters(config, rsc) # maps config.register_map('languages', Map) config.register_map('language', LanguageMap) config.register_map('parameter', ParameterMap) config.register_map('combination', CombinationMap) config.include('clld.web.adapters') for icon in ICONS: config.registry.registerUtility(icon, interfaces.IIcon, name=icon.name) config.registry.registerUtility(ORDERED_ICONS, interfaces.IIconList) config.registry.registerUtility(MapMarker(), interfaces.IMapMarker) # # inspect default locations for views and templates: # home_comp = OrderedDict() for name, template in [ ('introduction', False), ('about', False), ('terms', False), ('glossary', False), ('history', False), ('changes', False), ('credits', False), ('legal', True), ('download', True), ('contact', True), ('help', False), ]: home_comp[name] = template if pkg_dir.joinpath('templates').exists(): for p in pkg_dir.joinpath('templates').iterdir(): if p.stem in home_comp and p.suffix == '.mako': home_comp[p.stem] = True for name, template in home_comp.items(): if template: config.add_page(name) config.add_settings( {'home_comp': [k for k in home_comp.keys() if home_comp[k]]}) if 'clld.favicon' not in config.registry.settings: favicon = {'clld.favicon': 'clld:web/static/images/favicon.ico'} # hard to test (in particular on travis) and without too much consequence # (and the consequences faced are easy to spot). if pkg_dir.joinpath('static', 'favicon.ico').exists(): # pragma: no cover favicon['clld.favicon'] = root_package + ':static/favicon.ico' config.add_settings(favicon) config.add_settings({ 'clld.favicon_hash': md5(abspath_from_asset_spec(config.registry.settings['clld.favicon'])) }) translation_dirs = ['clld:locale'] if pkg_dir.joinpath('locale').exists(): translation_dirs.append('%s:locale' % root_package) # pragma: no cover config.add_translation_dirs(*translation_dirs) if pkg_dir.joinpath( 'static/publisher_logo.png').exists(): # pragma: no cover config.add_settings({ 'clld.publisher_logo': '%s:static/publisher_logo.png' % root_package }) if asbool(config.registry.settings.get('clld.pacific_centered_maps')): geojson.pacific_centered() v = maybe_import('%s.views' % root_package, pkg_dir=pkg_dir) if v: config.scan(v) # pragma: no cover menuitems = config.registry.settings.get( 'clld.menuitems_list', ['contributions', 'parameters', 'languages', 'contributors']) config.register_menu(('dataset', dict(label='Home')), *menuitems) config.include('pyramid_mako') for name in ['adapters', 'datatables', 'maps']: mod = maybe_import('%s.%s' % (root_package, name), pkg_dir=pkg_dir) if mod and hasattr(mod, 'includeme'): config.include(mod) config.register_download(CldfDownload(common.Dataset, root_package))
def get_configurator(pkg, *utilities, **kw): """ .. seealso:: https://groups.google.com/d/msg/pylons-discuss/Od6qIGaLV6A/3mXVBQ13zWQJ """ kw.setdefault('package', pkg) routes = kw.pop('routes', []) config = Configurator(**kw) json_renderer = JSON() json_renderer.add_adapter(datetime.datetime, lambda obj, req: obj.isoformat()) json_renderer.add_adapter(datetime.date, lambda obj, req: obj.isoformat()) config.add_renderer('json', json_renderer) jsonp_renderer = JSONP(param_name='callback') jsonp_renderer.add_adapter(datetime.datetime, lambda obj, req: obj.isoformat()) jsonp_renderer.add_adapter(datetime.date, lambda obj, req: obj.isoformat()) config.add_renderer('jsonp', jsonp_renderer) for name, pattern in routes: config.add_route(name, pattern) config.set_request_factory(ClldRequest) config.registry.registerUtility(CtxFactoryQuery(), interfaces.ICtxFactoryQuery) config.registry.registerUtility(OlacConfig(), interfaces.IOlacConfig) # initialize the db connection engine = engine_from_config(config.registry.settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.bind = engine config.add_settings({ 'pyramid.default_locale_name': 'en', 'clld.pkg': config.package_name, 'clld.parameters': {} }) if 'clld.files' in config.registry.settings: # deployment-specific location of static data files abspath = path(config.registry.settings['clld.files']).abspath() config.add_settings({'clld.files': abspath}) config.add_static_view('files', abspath) # event subscribers: config.add_subscriber(add_localizer, events.NewRequest) config.add_subscriber(init_map, events.ContextFound) config.add_subscriber( partial(add_renderer_globals, maybe_import('%s.util' % config.package_name)), events.BeforeRender) # # make it easy to register custom functionality # for name, func in { 'register_datatable': partial(register_cls, interfaces.IDataTable), 'register_map': partial(register_cls, interfaces.IMap), 'register_menu': register_menu, 'register_resource': register_resource, 'register_adapter': register_adapter, 'register_download': register_download, 'add_route_and_view': add_route_and_view, 'add_settings_from_file': add_settings_from_file, 'add_301': add_301, 'add_410': add_410, }.items(): config.add_directive(name, func) # # routes and views # config.add_static_view('clld-static', 'clld:web/static') config.add_static_view('static', '%s:static' % config.package_name) config.add_route_and_view('_js', '/_js', js, http_cache=3600) # add some maintenance hatches config.add_route_and_view('_raise', '/_raise', _raise) config.add_route_and_view('_ping', '/_ping', _ping, renderer='json') # sitemap support: config.add_route_and_view('robots', '/robots.txt', robots) config.add_route_and_view('sitemapindex', '/sitemap.xml', sitemapindex) config.add_route_and_view('sitemap', '/sitemap.{rsc}.{n}.xml', sitemap) config.add_route('resourcemap', '/resourcemap.json') config.add_view(resourcemap, route_name='resourcemap', renderer='jsonp') config.add_route_and_view('select_combination', '/_select_combination', select_combination) # TODO: remove google site verification for personal account! should be configurable! config.add_route('google-site-verification', 'googlebbc8f4da1abdc58b.html') config.add_view(lambda r: Response( 'google-site-verification: googlebbc8f4da1abdc58b.html'), route_name='google-site-verification') config.add_route_and_view('unapi', '/unapi', unapi) config.add_route_and_view('olac', '/olac', olac) for rsc in RESOURCES: name, model = rsc.name, rsc.model factory = partial(ctx_factory, model, 'index') config.add_route_and_view(rsc.plural, '/%s' % rsc.plural, index_view, factory=factory) config.register_datatable( rsc.plural, getattr(datatables, rsc.plural.capitalize(), DataTable)) config.register_adapter( getattr(excel, rsc.plural.capitalize(), excel.ExcelAdapter), rsc.interface) _kw = dict(factory=partial(ctx_factory, model, 'rsc')) if model == common.Dataset: pattern = '/' _kw['alt_route_pattern'] = '/void.{ext}' else: pattern = '/%s/{id:[^/\.]+}' % rsc.plural config.add_route_and_view(name, pattern, resource_view, **_kw) # maps config.register_map('languages', Map) config.register_map('language', LanguageMap) config.register_map('parameter', ParameterMap) config.register_map('combination', CombinationMap) config.include('clld.web.adapters') for icon in ICONS: config.registry.registerUtility(icon, interfaces.IIcon, name=icon.name) config.registry.registerUtility(MapMarker(), interfaces.IMapMarker) # # now we exploit the default package layout as created via the CLLD scaffold: # # note: the following exploits the import time side effect of modifying the webassets # environment! maybe_import('%s.assets' % config.package_name) pkg_dir = path(config.package.__file__).dirname().abspath() # # inspect default locations for views and templates: # home_comp = OrderedDict() for name, template in [ ('introduction', False), ('about', False), ('terms', False), ('glossary', False), ('history', False), ('changes', False), ('credits', False), ('legal', True), ('download', True), ('contact', True), ('help', False), ]: home_comp[name] = template if pkg_dir.joinpath('templates').exists(): for p in pkg_dir.joinpath('templates').files(): if p.namebase in home_comp and p.ext == '.mako': home_comp[p.namebase] = True views = maybe_import('%s.views' % config.package_name) for name, template in home_comp.items(): if template: config.add_route_and_view(name, '/' + name, getattr(views, name, lambda r: {}), renderer=name + '.mako') config.add_settings( {'home_comp': [k for k in home_comp.keys() if home_comp[k]]}) if 'clld.favicon' not in config.registry.settings: favicon = {'clld.favicon': 'clld:web/static/images/favicon.ico'} # hard to test (in particular on travis) and without too much consequence # (and the consequences faced are easy to spot). if pkg_dir.joinpath('static', 'favicon.ico').exists(): # pragma: no cover favicon[ 'clld.favicon'] = config.package_name + ':static/favicon.ico' config.add_settings(favicon) with open(abspath_from_asset_spec( config.registry.settings['clld.favicon'])) as fp: fh = md5() fh.update(fp.read()) config.add_settings({'clld.favicon_hash': fh.hexdigest()}) if pkg_dir.joinpath('locale').exists(): config.add_translation_dirs('clld:locale', '%s:locale' % config.package_name) if pkg_dir.joinpath( 'static/publisher_logo.png').exists(): # pragma: no cover config.add_settings({ 'clld.publisher_logo': '%s:static/publisher_logo.png' % config.package_name }) config.add_settings_from_file(pkg_dir.joinpath('appconf.ini')) v = maybe_import('%s.views' % config.package_name) if v: config.scan(v) # pragma: no cover menuitems = OrderedDict( dataset=partial(menu_item, 'dataset', label='Home')) for plural in config.registry.settings.get( 'clld.menuitems_list', ['contributions', 'parameters', 'languages', 'contributors']): menuitems[plural] = partial(menu_item, plural) config.registry.registerUtility(menuitems, interfaces.IMenuItems) config.include('pyramid_mako') for utility, interface in utilities: config.registry.registerUtility(utility, interface) return config