def parse_loader_options_from_settings(settings, prefix, maybe_dotted, package): """ Parse options for use with the SmartAssetSpecLoader.""" package = package or '__main__' def sget(name, default=None): return settings.get(prefix + name, default) debug = sget('debug_templates', None) if debug is None: # bw-compat prior to checking debug_templates for specific prefix debug = settings.get('debug_templates', None) debug = asbool(debug) input_encoding = sget('input_encoding', 'utf-8') # get jinja2 directories directories = parse_multiline(sget('directories') or '') directories = [abspath_from_asset_spec(d, package) for d in directories] if package != '__main__': directories.insert(0, abspath_from_asset_spec('', package)) return dict( debug=debug, encoding=input_encoding, searchpath=directories, )
def _get_asset_source_fileinfo(self, environment, template): if getattr(environment, '_default_package', None) is not None: pname = environment._default_package filename = abspath_from_asset_spec(template, pname) else: filename = abspath_from_asset_spec(template) fileinfo = FileInfo(filename, self.encoding) return fileinfo
def parse_options_from_settings(settings, settings_prefix, maybe_dotted): """ Parse options for use with Mako's TemplateLookup from settings.""" def sget(name, default=None): return settings.get(settings_prefix + name, default) reload_templates = sget('reload_templates', None) if reload_templates is None: reload_templates = settings.get('pyramid.reload_templates', None) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) future_imports = sget('future_imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): # Since we parse a value that comes from an .ini config, # we treat whitespaces and newline characters equally as list item separators. directories = aslist(directories, flatten=True) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: error_handler = maybe_dotted(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = aslist(default_filters) if imports is not None: if not is_nonstr_iter(imports): imports = aslist(imports, flatten=False) if future_imports is not None: if not is_nonstr_iter(future_imports): future_imports = aslist(future_imports) if preprocessor is not None: preprocessor = maybe_dotted(preprocessor) return dict( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, future_imports=future_imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor, )
def renderer_factory(info): path = info.name registry = info.registry settings = info.settings lookup = registry.queryUtility(IMakoLookup) if lookup is None: reload_templates = settings.get('reload_templates', False) directories = settings.get('mako.directories', None) module_directory = settings.get('mako.module_directory', None) input_encoding = settings.get('mako.input_encoding', 'utf-8') error_handler = settings.get('mako.error_handler', None) default_filters = settings.get('mako.default_filters', 'h') imports = settings.get('mako.imports', None) strict_undefined = settings.get('mako.strict_undefined', 'false') preprocessor = settings.get('mako.preprocessor', None) if directories is None: raise ConfigurationError( 'Mako template used without a ``mako.directories`` setting') if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [ abspath_from_asset_spec(d) for d in directories ] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: dotted = DottedNameResolver(info.package) error_handler = dotted.maybe_resolve(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter( None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) strict_undefined = asbool(strict_undefined) if preprocessor is not None: dotted = DottedNameResolver(info.package) preprocessor = dotted.maybe_resolve(preprocessor) lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor) registry_lock.acquire() try: registry.registerUtility(lookup, IMakoLookup) finally: registry_lock.release() return MakoLookupTemplateRenderer(path, lookup)
def renderer_factory(info): path = info.name registry = info.registry settings = info.settings lookup = registry.queryUtility(IMakoLookup) if lookup is None: reload_templates = settings.get('reload_templates', False) directories = settings.get('mako.directories', None) module_directory = settings.get('mako.module_directory', None) input_encoding = settings.get('mako.input_encoding', 'utf-8') error_handler = settings.get('mako.error_handler', None) default_filters = settings.get('mako.default_filters', 'h') imports = settings.get('mako.imports', None) strict_undefined = settings.get('mako.strict_undefined', 'false') preprocessor = settings.get('mako.preprocessor', None) if directories is None: raise ConfigurationError( 'Mako template used without a ``mako.directories`` setting') if not hasattr(directories, '__iter__'): directories = filter(None, directories.splitlines()) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: dotted = DottedNameResolver(info.package) error_handler = dotted.maybe_resolve(error_handler) if default_filters is not None: if not hasattr(default_filters, '__iter__'): default_filters = filter(None, default_filters.splitlines()) if imports is not None: if not hasattr(imports, '__iter__'): imports = filter(None, imports.splitlines()) strict_undefined = asbool(strict_undefined) if preprocessor is not None: dotted = DottedNameResolver(info.package) preprocessor = dotted.maybe_resolve(preprocessor) lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor) registry_lock.acquire() try: registry.registerUtility(lookup, IMakoLookup) finally: registry_lock.release() return MakoLookupTemplateRenderer(path, lookup)
def _initialize(event): settings = event.app.registry.settings if not asbool(settings.get('scss.reload')): log.debug('On-the-fly SCSS compilation disabled') compile.closure = lambda: None return log.debug('On-the-fly SCSS compilation launched') app_name = __name__.split('.')[0] scss.initialize(settings['app.static.url'], abspath_from_asset_spec(':'.join([app_name, 'static']))) assets_dir = abspath_from_asset_spec(settings['scss.directory']) options = dict(load_paths=[assets_dir], compress=asbool(settings.get('scss.compress'))) compile.closure = partial(scss.compile, assets_dir, options)
def _initialize(event): settings = event.app.registry.settings if not asbool(settings.get('scss.reload')): log.debug('On-the-fly SCSS compilation disabled') compile.closure = lambda: None return log.debug('On-the-fly SCSS compilation launched') app_name = __name__.split('.')[0] scss.initialize( settings['app.static.url'], abspath_from_asset_spec(':'.join([app_name, 'static']))) assets_dir = abspath_from_asset_spec(settings['scss.directory']) options = dict(load_paths=[assets_dir], compress=asbool(settings.get('scss.compress'))) compile.closure = partial(scss.compile, assets_dir, options)
def parse_loader_options_from_settings(settings, prefix, maybe_dotted, package): """ Parse options for use with the SmartAssetSpecLoader.""" package = package or '__main__' def sget(name, default=None): return settings.get(prefix + name, default) debug = sget('debug_templates', None) if debug is None: # bw-compat prior to checking debug_templates for specific prefix debug = settings.get('debug_templates', None) debug = asbool(debug) input_encoding = sget('input_encoding', 'utf-8') # get jinja2 directories directories = parse_multiline(sget('directories') or '') directories = [abspath_from_asset_spec(d, package) for d in directories] return dict( debug=debug, encoding=input_encoding, searchpath=directories, )
def get_template(self, uri): """Fetch a template from the cache, or check the filesystem for it In addition to the basic filesystem lookup, this subclass will use pkg_resource to load a file using the asset specification syntax. """ isabs = os.path.isabs(uri) if (not isabs) and (':' in uri): # Windows can't cope with colons in filenames, so we replace the # colon with a dollar sign in the filename mako uses to actually # store the generated python code in the mako module_directory or # in the temporary location of mako's modules adjusted = uri.replace(':', '$') try: if self.filesystem_checks: return self._check(adjusted, self._collection[adjusted]) else: return self._collection[adjusted] except KeyError: pname, path = resolve_asset_spec(uri) srcfile = abspath_from_asset_spec(path, pname) if os.path.isfile(srcfile): return self._load(srcfile, adjusted) raise exceptions.TopLevelLookupException( "Can not locate template for uri %r" % uri) return TemplateLookup.get_template(self, uri)
def setup_for_pyramid(config, translator=translator, template_dirs=( 'deform_bootstrap_extra:templates', 'deform_bootstrap:templates', 'deform:templates')): '''Set deform up for i18n and give its template loader the correct directory hierarchy. This includes deform_bootstrap, so the app developer must not. ''' global already_setup if already_setup: return from .. import monkeypatch_colander monkeypatch_colander() config.add_translation_dirs('colander:locale', 'deform:locale',) # 'deform_bootstrap_extra:locale') config.add_static_view('deform', 'deform:static') config.add_static_view('deform_bootstrap_extra', 'deform_bootstrap_extra:static') config.include('deform_bootstrap') # dirs = tuple([resource_filename(*dir.split(':')) # for dir in template_dirs]) dirs = tuple([abspath_from_asset_spec(dir) for dir in template_dirs]) d.Form.set_zpt_renderer(dirs, translator=translator) already_setup = True
def _build_handler(self, asset, request): assetpath = os.path.abspath(abspath_from_asset_spec(asset)) if not assetpath.startswith(self.basepath): # make sure url scheme wasn't tricked into going into parent dirs return Curry(HTTPNotFound, comment=request.url[len(request.application_url):]) if os.path.isdir(assetpath): index = self.find_index(assetpath) if index: logger.debug('serving default index file: ' + index) return Curry(render_to_response, renderer_name=index, value={}) return Curry(self.render_listing, path=assetpath) if os.path.isfile(assetpath): helper = RendererHelper(name=asset, registry=request.registry) try: if helper.renderer is not None: return Curry(helper.render_to_response, value={}, system_values=None) except ValueError: pass def serve_file(request, application): return request.get_response(application) fileapp = FileApp(filename=assetpath) return Curry(serve_file, application=fileapp) return Curry(HTTPNotFound, comment=request.url[len(request.application_url):])
def _load_fixtures(self): self.fixtures = {} fixture_path = abspath_from_asset_spec('pyramid_scss.tests:fixtures') for path, dirs, files in os.walk(fixture_path): for name in files: with open(os.path.join(path, name)) as f: self.fixtures.setdefault(name, f.read())
def __init__(self, manifest_spec, reload=False): package_name = caller_package().__name__ self.manifest_path = abspath_from_asset_spec(manifest_spec, package_name) self.reload = reload self._mtime = None if not reload: self._manifest = self.get_manifest()
def parse_options_from_settings(settings, settings_prefix, maybe_dotted): """ Parse options for use with Mako's TemplateLookup from settings.""" def sget(name, default=None): return settings.get(settings_prefix + name, default) reload_templates = settings.get('pyramid.reload_templates', None) if reload_templates is None: reload_templates = settings.get('reload_templates', False) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: error_handler = maybe_dotted(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter( None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) if preprocessor is not None: preprocessor = maybe_dotted(preprocessor) return dict( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor, )
def register(): env = get_jinja2_environment(config, name) searchpaths = parse_multiline(searchpath) for folder in searchpaths: path = abspath_from_asset_spec(folder, config.package) if prepend: env.loader.searchpath.insert(0, path) else: env.loader.searchpath.append(path)
def parse_options_from_settings(settings, settings_prefix, maybe_dotted): """ Parse options for use with Mako's TemplateLookup from settings.""" def sget(name, default=None): return settings.get(settings_prefix + name, default) reload_templates = settings.get('pyramid.reload_templates', None) if reload_templates is None: reload_templates = settings.get('reload_templates', False) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: error_handler = maybe_dotted(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter(None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) if preprocessor is not None: preprocessor = maybe_dotted(preprocessor) return dict( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor, )
def stability(req): fs = jsonload(abspath_from_asset_spec('grambank:static/stability.json')) #lfv = DBSession.query(Value).join(Value.valueset)\ # .options( # joinedload(Value.valueset, ValueSet.language), # joinedload(Value.valueset, ValueSet.parameter) # ) #trp = [(v.id,) for v in lfv] #sorted(fs.items(), key = lambda (f, s): s, reverse=True) return {'data': fs}
def test_mtime(self): from pyramid_jinja2 import FileInfo from pyramid.asset import abspath_from_asset_spec filename = abspath_from_asset_spec('templates/helloworld.jinja2', 'pyramid_jinja2.tests') fi = FileInfo(filename) assert '_mtime' not in fi.__dict__ assert fi.mtime is not None assert fi.mtime == fi._mtime
def _load_fixtures(self): self.fixtures = {} fixture_path = abspath_from_asset_spec('pyramid_scss.tests:fixtures') for path, dirs, files in os.walk(fixture_path): for name in files: if name.endswith('.png'): mode = 'rb' else: mode = 'r' with open(os.path.join(path, name), mode) as f: self.fixtures.setdefault(name, f.read())
def stability(req): fs = jsonload(abspath_from_asset_spec('culturebank:static/stability.json')) #lfv = DBSession.query(Value).join(Value.valueset)\ # .options( # joinedload(Value.valueset, ValueSet.language), # joinedload(Value.valueset, ValueSet.parameter) # ) #trp = [(v.id,) for v in lfv] #sorted(fs.items(), key = lambda (f, s): s, reverse=True) return {'data': fs}
def pystache_renderer_factory(info): template = os.path.join( abspath_from_asset_spec('pubssite:templates', False), info.name) f = open(template) s = f.read() f.close() def _render(value, system): return pystache.render(s, value) return _render
def dependency(req): print "HEJ2" deps = jsonload(abspath_from_asset_spec('grambank:static/dependencies.json')) #lfv = DBSession.query(Value).join(Value.valueset)\ # .options( # joinedload(Value.valueset, ValueSet.language), # joinedload(Value.valueset, ValueSet.parameter) # ) #trp = [(v.id,) for v in lfv] #sorted(fs.items(), key = lambda (f, s): s, reverse=True) return {'data': deps}
def add_asset_views(config, spec, filename=None, filenames=None, http_cache=None): """ A pyramid directive that takes an asset spec and a file name or list of filenames and adds them to the pyramid config via the `add_view` function. These files added by this directive will be served relative to the Root of the application. For Example: config.add_asset_views("mymodule:static", "favicon.ico") Alternatively you could use argument expansion with longer file lists: filenames = ['favicon.ico', 'robots.txt', 'humans.txt', 'crossdomain.xml'] config.add_asset_views("mymodule:static", filenames=filenames) favicon.ico and robots.txt located in mymodule/static/ will now be served from /favicon.ico and /robots.txt respectively. Optionally the http_cache argument may be set with a number that represents a length of time in seconds. For Example: config.add_asset_views("mymodule:static", "favicon.ico", http_cache=50000) Large files are not meant to be served this way as the current implementation reads the entire file into memory before generating the response object. The main purpose of this module is to include assets that must be served from the root of the domain such as favicon.ico, robots.txt, and crossdomain.xml. """ if filename is None and filenames is None: raise NoFilenamesProvided path = abspath_from_asset_spec(spec) if not filenames: filenames = [] if filename: filenames.append(filename) for name in filenames: content_type = mimetypes.guess_type(name, strict=False)[0] if content_type is None: content_type = 'application/octet-stream' filename = os.path.join(path, name) body = open(filename, 'rb').read() last_modified = os.stat(filename).st_mtime config.add_view(asset_view_factory(body, content_type, last_modified, http_cache=http_cache), name=name)
def main(global_config, **settings): """ Main entry point for web scripts """ config = Configurator(settings=settings) _robots = open(abspath_from_asset_spec('amppki:static/robots.txt')).read() _robots_response = Response(content_type='text/plain', body=_robots) config.add_view(lambda x: _robots_response, name='robots.txt') config.add_route("sign", "sign") config.add_route("cert", "cert/{ampname}/{signature}") config.add_route("default", "/*args") config.scan() return config.make_wsgi_app()
def __init__(self, assetspec, package=None): pname = package if not isinstance(package, basestring) \ and hasattr(package, '__name__'): pname = pname.__name__ if ':' not in assetspec and package: assetspec = pname + ':' + assetspec if not assetspec.endswith('/'): assetspec += '/' self.assetspec = assetspec self.basepath = os.path.abspath(abspath_from_asset_spec(assetspec)) if not self.dir_exists(self.basepath): raise ValueError('%s <-> %s does not exist as a directory' % (assetspec, self.basepath))
def get_source(self, environment, template): # keep legacy asset: prefix checking that bypasses # source path checking altogether if template.startswith('asset:'): template = template[6:] # load template directly from the filesystem filename = abspath_from_asset_spec(template) fi = FileInfo(filename, self.encoding) if os.path.isfile(fi.filename): return fi.contents, fi.filename, fi.uptodate # fallback to search-path lookup try: return FileSystemLoader.get_source(self, environment, template) except TemplateNotFound as ex: message = ex.message message += ('; asset=%s; searchpath=%r' % (template, self.searchpath)) raise TemplateNotFound(name=ex.name, message=message)
def coverage(req): gl = jsonload(abspath_from_asset_spec('grambank:static/stats_glottolog.json')) stats = defaultdict(lambda: defaultdict(lambda: defaultdict(int))) for ma in gl: for dt in gl[ma]: ids = gl[ma][dt] isolates = select( [Language.__table__.c.id]).where(Language.__table__.c.id.in_(ids)) families = select( [Family.__table__.c.id]).where(Family.__table__.c.id.in_(ids)) stats[ma][dt] = dict( glottolog=len(ids), grambank=DBSession.query(isolates.union(families).alias('u')).count()) stats[ma]['total'] = {} for src in ['glottolog', 'grambank']: stats[ma]['total'][src] = \ stats[ma]['grammar'][src] + stats[ma]['grammarsketch'][src] return dict(stats=stats)
def __call__(self, layers, system): request = system['request'] # get image width and height width = 256 height = 256 # get image bbox z = int(request.matchdict['z']) x = int(request.matchdict['x']) y = int(request.matchdict['y']) step = max / (2**(int(z) - 1)) xmin = x * step - max ymin = max - y * step xmax = (x + 1) * step - max ymax = max - (y + 1) * step bbox = Box2d(xmin, ymax, xmax, ymin) m = Map(width, height) load_map(m, abspath_from_asset_spec('osmtm:views/map.xml')) for l in layers: m.layers.append(l) m.zoom_to_box(bbox) format = request.matchdict['format'] if format == 'png': im = Image(width, height) render(m, im, 1, 1) request.response_content_type = 'image/png' return im.tostring('png') elif format == 'json': grid = Grid(width, height) render_layer(m, grid, layer=0, fields=['id']) utfgrid = grid.encode('utf', resolution=4) return json.dumps(utfgrid)
def __call__(self, layers, system): request = system['request'] # get image width and height width = 256 height = 256 # get image bbox z = int(request.matchdict['z']) x = int(request.matchdict['x']) y = int(request.matchdict['y']) step = max/(2**(int(z) - 1)) xmin = x*step-max ymin = max-y*step xmax = (x+1)*step-max ymax = max-(y+1)*step bbox = Box2d(xmin, ymax, xmax, ymin) m = Map(width, height) load_map(m, abspath_from_asset_spec('osmtm:views/map.xml')) for l in layers: m.layers.append(l) m.zoom_to_box(bbox) format = request.matchdict['format'] if format == 'png': im = Image(width, height) render(m, im, 1, 1) request.response_content_type = 'image/png' return im.tostring('png') elif format == 'json': grid = Grid(width, height) render_layer(m, grid, layer=0, fields=['id']) utfgrid = grid.encode('utf', resolution=4) return json.dumps(utfgrid)
def bootstrap_data(registry): """ create sample content """ crowd_cfg = ptah.get_settings(ptah_crowd.CFG_ID_CROWD, registry) admin_id = crowd_cfg['admin-login'] admin = ptah_crowd.CrowdFactory().get_user_bylogin(admin_id) root = APP_FACTORY() # give manager role to admin if admin.__uri__ not in root.__local_roles__: root.__local_roles__[admin.__uri__] = [Manager.id] # set authcontext so content shows created by admin ptah.auth_service.set_userid(admin.__uri__) # create default page if 'front-page' not in root.keys(): page = Page(title='Welcome to Ptah') page.text = open(abspath_from_asset_spec('ptah_minicms:welcome.pt'), 'rb').read() root['front-page'] = page
def bootstrap_data(registry): """ create sample content """ crowd_cfg = ptah.get_settings(ptah_crowd.CFG_ID_CROWD, registry) admin_id = crowd_cfg['admin-login'] admin = ptah_crowd.CrowdFactory().get_user_bylogin(admin_id) root = APP_FACTORY() # give manager role to admin if admin.__uri__ not in root.__local_roles__: root.__local_roles__[admin.__uri__] = [Manager.id] # set authcontext so content shows created by admin ptah.auth_service.set_userid(admin.__uri__) # create default page if 'front-page' not in root.keys(): page = Page(title='Welcome to Ptah') page.text = open( abspath_from_asset_spec('ptah_minicms:welcome.pt'), 'rb').read() root['front-page'] = page
def get_template(self, uri): """Fetch a template from the cache, or check the filesystem for it In addition to the basic filesystem lookup, this subclass will use pkg_resource to load a file using the asset specification syntax. """ isabs = os.path.isabs(uri) if (not isabs) and (':' in uri): try: if self.filesystem_checks: return self._check(uri, self._collection[uri]) else: return self._collection[uri] except KeyError: pname, path = resolve_asset_spec(uri) srcfile = abspath_from_asset_spec(path, pname) if os.path.isfile(srcfile): return self._load(srcfile, uri) raise exceptions.TopLevelLookupException( "Can not locate template for uri %r" % uri) return TemplateLookup.get_template(self, uri)
def __call__(self, info): mapfile = abspath_from_asset_spec(info.name) def _render(value, system): request = system['request'] if not isinstance(value, tuple): value = (None, value) layer_name, collection = value if not hasattr(collection, 'features'): raise ValueError('renderer is not passed a feature collection') # get image width and height try: img_width = int(request.params.get('img_width', 256)) except: request.response_status = 400 return 'incorrect img_width' try: img_height = int(request.params.get('img_height', 256)) except: request.response_status = 400 return 'incorrect img_height' # get image format try: img_format = request.params.get( 'img_format', request.matchdict.get('format', 'png')) img_format = str(img_format) except: request.response_status = 400 return 'incorrect img_format' # get image bbox img_bbox = request.params.get('img_bbox', request.params.get('bbox')) if img_bbox: try: img_bbox = map(float, img_bbox.split(',')) except ValueError: request.response_status = 400 return 'incorrect img_bbox' img_bbox = Box2d(*img_bbox) m = Map(img_width, img_height) load_map(m, mapfile) if len(m.layers) == 0: raise ValueError('no layer in the mapnik map') # if no layer_name is provided then, by convention, use # the first layer in the mapnik map if layer_name is None: layer_name = m.layers[0].name layer = self._set_layer_in_map(m, layer_name) layer.datasource = self._create_datasource(collection) m.zoom_to_box(img_bbox or layer.envelope()) im = Image(img_width, img_height) render(m, im, 1, 1) # get the image format from the request request.response.content_type = 'image/%s' % img_format return im.tostring(img_format) return _render
def __call__(self, info): path = info.name registry = info.registry settings = info.settings settings_prefix = self.settings_prefix if settings_prefix is None: settings_prefix = info.type +'.' lookup = registry.queryUtility(IMakoLookup, name=settings_prefix) def sget(name, default=None): return settings.get(settings_prefix + name, default) if lookup is None: reload_templates = settings.get('pyramid.reload_templates', None) if reload_templates is None: reload_templates = settings.get('reload_templates', False) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [ abspath_from_asset_spec(d) for d in directories ] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: dotted = DottedNameResolver(info.package) error_handler = dotted.maybe_resolve(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter( None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) if preprocessor is not None: dotted = DottedNameResolver(info.package) preprocessor = dotted.maybe_resolve(preprocessor) lookup = PkgResourceTemplateLookup( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor ) registry_lock.acquire() try: registry.registerUtility(lookup, IMakoLookup, name=settings_prefix) finally: registry_lock.release() return MakoLookupTemplateRenderer(path, lookup)
def javascript_link(request, asset_spec): real_path = abspath_from_asset_spec(asset_spec) url_path = request.static_path(asset_spec) return html.javascript_link(url_path, real_path, cache_bust='md5')
def coverage(req): gl = jsonload( abspath_from_asset_spec('grambank:static/stats_by_macroarea.json')) stats = defaultdict(lambda: defaultdict(lambda: defaultdict(int))) for ma in gl: for dt in gl[ma]: ids = gl[ma][dt] isolates = select([Language.__table__.c.id ]).where(Language.__table__.c.id.in_(ids)) families = select([Family.__table__.c.id ]).where(Family.__table__.c.id.in_(ids)) stats[ma][dt] = dict( glottolog=len(ids), grambank=DBSession.query( isolates.union(families).alias('u')).count()) stats[ma]['total'] = {} for src in ['glottolog', 'grambank']: stats[ma]['total'][src] = \ stats[ma]['grammar'][src] + stats[ma]['grammarsketch'][src] gl = jsonload( abspath_from_asset_spec( 'grambank:static/stats_by_classification.json')) gb_langs = set([r[0] for r in DBSession.query(Language.id)]) cstats = OrderedDict() for fid, spec in sorted(gl.items(), key=lambda k: k[1]['name']): d = dict(macroareas=spec['macroareas'], grammar=Counter(), grammarsketch=Counter(), total=Counter(), covered=gb_langs.intersection(set(spec['extension'])), isolate=not bool(spec.get('subgroups')), subgroups={}) if not spec.get('subgroups'): # an isolate! d[spec['doctype']].update(['glottolog']) d['total'].update(['glottolog']) if gb_langs.intersection(set(spec['extension'])): d[spec['doctype']].update(['grambank']) d['total'].update(['grambank']) for sfid, sub in spec.get('subgroups', {}).items(): if not sub.get('subgroups'): sub['name'] = '%s*' % sub['name'] d[sub['doctype']].update(['glottolog']) d['total'].update(['glottolog']) if gb_langs.intersection(set(sub['extension'])): d[sub['doctype']].update(['grambank']) d['total'].update(['grambank']) d['subgroups'][(sfid, sub['name'])] = dict( macroareas=spec['macroareas'], covered=gb_langs.intersection(set(sub['extension'])), grammar=Counter(), grammarsketch=Counter(), total=Counter()) if not sub.get('subgroups'): # a language attached directly to the top-level family d['subgroups'][(sfid, sub['name'])][sub['doctype']].update( ['glottolog']) d['subgroups'][(sfid, sub['name'])]['total'].update(['glottolog']) if gb_langs.intersection(set(sub['extension'])): d['subgroups'][(sfid, sub['name'])][sub['doctype']].update( ['grambank']) d['subgroups'][(sfid, sub['name'])]['total'].update(['grambank']) for ssfid, ssub in sub.get('subgroups', {}).items(): if ssub['doctype']: d['subgroups'][(sfid, sub['name'])][ssub['doctype']].update( ['glottolog']) d['subgroups'][(sfid, sub['name'])]['total'].update( ['glottolog']) if gb_langs.intersection(set(ssub['extension'])): d['subgroups'][(sfid, sub['name'])][ssub['doctype']].update( ['grambank']) d['subgroups'][(sfid, sub['name'])]['total'].update( ['grambank']) cstats[(fid, spec['name'])] = d return dict( stats=stats, cstats=cstats, macroareas=jsonload( abspath_from_asset_spec('grambank:static/stats_macroareas.json')))
def _get_absolute_source(self, template): filename = abspath_from_asset_spec(template) fi = FileInfo(filename, self.encoding) if os.path.isfile(fi.filename): return fi.contents, fi.filename, fi.uptodate
def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ nntscport = int(settings.get('ampweb.nntscport', 61234)) settings['ampweb.nntscport'] = nntscport config = Configurator(settings=settings, root_factory=Root) # only enable auth if the secret is set secret = settings.get('auth.secret') if secret is not None: authn_policy = AuthTktAuthenticationPolicy(settings.get('auth.secret'), hashalg='sha512', callback=groupfinder) authz_policy = ACLAuthorizationPolicy() config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) public = settings.get('auth.publicdata') if public is None or public in ["yes", "true", "True"]: # Allow any visitor to access the graphs/matrix/etc. # Configuration pages still require "edit" permission config.set_default_permission(NO_PERMISSION_REQUIRED) else: # Limit graphs/matrix/etc to users with "read" permissions. # Configuration pages still require "edit" permission config.set_default_permission("read") config.include('pyramid_chameleon') # Static content config.add_static_view('static', 'ampweb:static/', cache_max_age=3600) config.add_static_view('fonts', 'ampweb:static/fonts/', cache_max_age=3600) # TODO robots.txt only works from /robots.txt and by default we install # into /ampweb/ so it's available as /ampweb/robots.txt which does nothing # need to do special work to serve static files from the root # https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/static_assets/files.html#serving-a-single-file-from-the-root _robots = open(abspath_from_asset_spec('ampweb:static/robots.txt')).read() _robots_response = Response(content_type='text/plain', body=_robots) config.add_view(lambda x: _robots_response, name='robots.txt') # Management REST interface - certificates # TODO should this be here or instead in amppki? config.add_route("certificates", "api/v2/certificates/{name}") # Management REST interface - sites config.add_route("allsites", "api/v2/sites") config.add_route("onesite", "api/v2/sites/{name}") config.add_route("sitemeshes", "api/v2/sites/{name}/meshes") config.add_route("sitemesh", "api/v2/sites/{name}/meshes/{mesh:.*}") # Management REST interface - meshes config.add_route("allmeshes", "api/v2/meshes") config.add_route("onemesh", "api/v2/meshes/{mesh}") config.add_route("meshsites", "api/v2/meshes/{mesh}/sites") config.add_route("meshsite", "api/v2/meshes/{mesh}/sites/{name:.*}") config.add_route("meshtests", "api/v2/meshes/{mesh}/tests") # Management REST interface - site schedules config.add_route("site_schedules", "api/v2/sites/{name}/schedule") config.add_route("site_schedule", "api/v2/sites/{name}/schedule/{schedule_id}") config.add_route("site_schedule_status", "api/v2/sites/{name}/schedule/{schedule_id}/status") config.add_route( "site_schedule_destinations", "api/v2/sites/{name}/schedule/{schedule_id}/destinations") config.add_route( "site_schedule_destination", "api/v2/sites/{name}/schedule/{schedule_id}/destinations/{destination}" ) # Management REST interface - mesh schedules config.add_route("mesh_schedules", "api/v2/meshes/{name}/schedule") config.add_route("mesh_schedule", "api/v2/meshes/{name}/schedule/{schedule_id}") config.add_route("mesh_schedule_status", "api/v2/meshes/{name}/schedule/{schedule_id}/status") config.add_route( "mesh_schedule_destinations", "api/v2/meshes/{name}/schedule/{schedule_id}/destinations") config.add_route( "mesh_schedule_destination", "api/v2/meshes/{name}/schedule/{schedule_id}/destinations/{destination}" ) # Management REST interface - users config.add_route("allusers", "api/v2/users") config.add_route("user", "api/v2/users/{username}") config.add_route("user_status", "api/v2/users/{username}/status") # Management - site accessible configuration config.add_route('config', 'config/{name}') config.add_route('yaml', 'yaml/{name}') # web client view to the yaml schedule so it can have different permissions config.add_route('yaml_web', 'sites/view/{name}/yaml') # Dynamic content from views config.add_route('home', '/') config.add_route('login', 'login') config.add_route('logout', 'logout') config.add_route('api', 'api*params') config.add_route('matrix', 'matrix*params') config.add_route('graph', 'graph*params') config.add_route('view', 'view/*params') config.add_route('tabview', 'tabview*params') config.add_route('eventview', 'eventview*params') config.add_route('streamview', 'streamview*params') config.add_route('dashboard', 'dashboard') config.add_route('browser', 'browser') config.add_route('modal', 'modal*params') config.add_route('schedule_ui', 'schedule*params') config.add_route('meshes', 'meshes*params') config.add_route('sites', 'sites*params') config.add_route('users', 'users*params') config.add_route('changetime', 'changetime*params') config.add_route('rating', 'rating*params') config.scan() return config.make_wsgi_app()
def __init__(self, info): self.mapfile = abspath_from_asset_spec(info.name)
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) 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'}) 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, }.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('legal', '/legal', lambda r: {}, renderer='legal.mako') config.add_route_and_view('download', '/download', lambda r: {}, renderer='download.mako') config.add_route_and_view('contact', '/contact', lambda r: {}, renderer='contact.mako') 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('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.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() 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('%s:locale' % config.package_name) config.add_translation_dirs('clld:locale') 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) for utility, interface in utilities: config.registry.registerUtility(utility, interface) return config
def template_setup(config, request): module_dir = abspath_from_asset_spec('pyramid_crud:_mako_template_cache') config.add_settings({'mako.module_directory': module_dir}) config.include("pyramid_mako") config.commit()
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
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__ maybe_import('%s.assets' % root_package) pkg_dir = Path(config.root_package.__file__).parent.resolve() 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) # 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': root_package, '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', abspath.as_posix()) # 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)), 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_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) with open(abspath_from_asset_spec( config.registry.settings['clld.favicon']), mode='rb') as fp: fh = md5() fh.update(fp.read()) config.add_settings({'clld.favicon_hash': fh.hexdigest()}) 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) 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)) if mod and hasattr(mod, 'includeme'): config.include(mod) config.register_download(CldfDownload(common.Dataset, root_package))
def __call__(self, info): p = re.compile(r'(?P<asset>[\w_.:/-]+)' r'(?:\#(?P<defname>[\w_]+))?' r'(\.(?P<ext>.*))') asset, defname, ext = p.match(info.name).group('asset', 'defname', 'ext') path = '%s.%s' % (asset, ext) registry = info.registry settings = info.settings settings_prefix = self.settings_prefix if settings_prefix is None: settings_prefix = info.type + '.' lookup = registry.queryUtility(IMakoLookup, name=settings_prefix) def sget(name, default=None): return settings.get(settings_prefix + name, default) if lookup is None: reload_templates = settings.get('pyramid.reload_templates', None) if reload_templates is None: reload_templates = settings.get('reload_templates', False) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: dotted = DottedNameResolver(info.package) error_handler = dotted.maybe_resolve(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list( filter(None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) if preprocessor is not None: dotted = DottedNameResolver(info.package) preprocessor = dotted.maybe_resolve(preprocessor) lookup = PkgResourceTemplateLookup( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor) with registry_lock: registry.registerUtility(lookup, IMakoLookup, name=settings_prefix) return MakoLookupTemplateRenderer(path, defname, lookup)
def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ # Setup ------------------------------------------------------------------- # Pyramid Global Settings config = Configurator(settings=settings, root_factory=GlobalRootFactory) # Beaker Session Manager session_factory = pyramid_beaker.session_factory_from_settings(settings) config.set_session_factory(session_factory) # Parse/Convert setting keys that have specifyed datatypes settings = config.registry.settings for key in settings.keys(): settings[key] = convert_str_with_type(settings[key]) # Core Content Mount Tracker ---------------------------------------------- mount_sys = Mount(path=abspath_from_asset_spec('flexi:.')) mount_sys.add_path('assets' , file_filter=regex_file_filter_static) mount_sys.add_path('templates', file_filter=regex_file_filter_template) mount_sys.mounted = tuple(chain(mount_sys._transform_template_list(), mount_sys._transform_static_list(name='assets', path_join=['assets']))) # Addon Content Scan & Trackers ------------------------------------------- settings['content.path.absolute'] = abspath_from_asset_spec(settings['content.path'] ) settings['content.path.addons.absolute'] = abspath_from_asset_spec(settings['content.path.addons']) addon_core = Addon(path=settings['content.path.absolute'], data=dict(name='Core', static_mount='')) settings['addons'] = Addon.scan( path=settings['content.path.addons.absolute'], data_file_regex=settings['content.path.addons.identifyer'] ) addons = list(settings['addons'].values()) + [addon_core] # Core is added last because if it first in the mount order it wont surface the addon content settings['mounts'] = [mount_sys] + addons # Server Researt on change ----------------------------------------------- # Restart the server on content file change # If any of the mounted content files change, then we want the cache.manifest hash to change add_file_callback(lambda: map(operator.attrgetter('absolute'), reduce(operator.add, (mount.get_file_list() for mount in settings['mounts'])))) # Routes ------------------------------------------------------------------ # Static Routes config.add_static_view(name='assets', path=mount_sys.get_path('assets')) #cache_max_age=3600 for addon in addons: config.add_static_view(name='static/{0}'.format(addon.static_mount), path=addon.get_path('static')) settings['mako.directories'] = [ mount_sys.get_path('templates'), ] for addon in addons: settings['mako.directories'].append(addon.get_path('templates')) # View Routes config.add_route('cache_manifest', 'cache.manifest') config.add_route('favicon', 'favicon.ico') # Surpress repeated requests config.add_route('status', 'status') # Views ------------------------------------------------------------------- config.add_view('flexi.views.misc.traversal_template', context='flexi.traversal.TemplateResource') # Events ------------------------------------------------------------------ config.add_subscriber(add_template_helpers_to_event, pyramid.events.BeforeRender) # Register Aditional Includes --------------------------------------------- config.include('pyramid_mako') # The mako.directories value is updated in the scan for addons. We trigger the import here to include the correct folders. # Return ------------------------------------------------------------------ config.scan(ignore='.tests') return config.make_wsgi_app()