Пример #1
0
def configure_application(config):
    """
    Configure `sandglass.time` application.

    """
    config.add_translation_dirs('sandglass.time:locales/')
    config.include('sandglass.time.resource')

    json_renderer = JSONP(param_name='callback')
    json_renderer.add_adapter(datetime.datetime, json_datetime_adapter)
    config.add_renderer('json', json_renderer)

    # Add custom request methods
    extend_request_object(config)

    # Scan modules that need to be pre-loaded
    config.scan('sandglass.time.models')
    config.scan('sandglass.time.errorhandlers')

    # Attach sandglass.time resources to '/time' URL path prefix
    config.include(include_resources, route_prefix='time')
Пример #2
0
def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    authentication_policy = AuthenticationPolicy(
        settings['auth.secret'], cookie_name='shike.im')
    authorization_policy = ACLAuthorizationPolicy() 
    config = Configurator(settings=settings)
    config.set_root_factory('hzsxactivitymanagesite.resources.RootFactory')
    config.set_authentication_policy(authentication_policy)
    config.set_authorization_policy(authorization_policy)
    
    jsonp = JSONP(param_name='callback')
    jsonp.add_adapter(ObjectId, objectid_adapter)
    jsonp.add_adapter(DBRef, dbref_adapter)
    jsonp.add_adapter(datetime.datetime, datetime_adapter)
    config.add_renderer('jsonp', jsonp)
    config.add_subscriber(real_ip_hook, NewRequest)
    config.set_request_property(get_db, "db", reify=True)
    config.set_request_property(get_fs, "fs", reify=True)
    config.set_request_property(get_user, "user", reify=True)
    
    config.add_static_view('static', 'static', cache_max_age=3600)
    config.include("hzsxactivitymanagesite.views.home")
    config.add_forbidden_view("hzsxactivitymanagesite.views.forbidden_view",  renderer="json")
    config.add_notfound_view("hzsxactivitymanagesite.views.notfound_view", renderer="json")
    config.add_view("hzsxactivitymanagesite.views.apierror_view", context='hzsxactivitymanagesite.exceptions.APIError', renderer='json')
    config.add_view("hzsxactivitymanagesite.views.pageerror_view", context='hzsxactivitymanagesite.exceptions.PageError', renderer='error.mako')
    return config.make_wsgi_app()
Пример #3
0
    }
    meta = MetadataSchema().serialize(obj.__dict__)
    # FIXME in_navigation is serialized as string instead of bool
    meta['in_navigation'] = bools[meta['in_navigation'].lower()]
    if include_messages:
        meta['messages'] = get_messages(request)
    if relmeta:
        # make data.relationships.meta object
        rel = dict()
        relmeta = dict()
        rel['meta'] = relational_metadata(obj, request)
        res['relationships'] = rel
    
    
    return dict(data=res, meta=meta)


jsonp = JSONP(param_name='callback')
jsonp.add_adapter(Content, serialize)
jsonp.add_adapter(colander._null, lambda obj, req: None)
jsonp.add_adapter(datetime.date, lambda obj, req: str(obj))
jsonp.add_adapter(datetime.datetime, lambda obj, req: obj.isoformat())
jsonp.add_adapter(datetime.time, lambda obj, req: str(obj))

contents_jsonp = JSONP(param_name='callback')


def includeme(config):
    config.add_renderer('kotti_jsonp', jsonp)
    config.scan(__name__)
Пример #4
0
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))
Пример #5
0
Файл: app.py Проект: esbesb/clld
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))
Пример #6
0
    class Encoder(json.JSONEncoder):

        def default(self, obj):
            """Convert ``obj`` to something JSON encoder can handle."""
            # if isinstance(obj, NamedTuple):
            #     obj = dict((k, getattr(obj, k)) for k in obj.keys())
            if isinstance(obj, decimal.Decimal):
                return str(obj)
            elif isinstance(obj, datetime_types):
                return str(obj)
            elif obj is colander.null:
                return None

            return basedefault(obj)

    return Encoder


def to_json(obj, default=None, **kw):
    return json.dumps(obj, cls=_encoder(default), **kw)


jsonp = JSONP(param_name='callback', serializer=to_json)
jsonp.add_adapter(Content, serialize)


def includeme(config):
    config.add_renderer('kotti_jsonp', jsonp)
    config.scan(__name__)
Пример #7
0
def create_jsonp_renderer():
    renderer = JSONP()
    renderer.add_adapter(datetime.date, datetime_adapter)
    renderer.add_adapter(datetime.datetime, datetime_adapter)
    renderer.add_adapter(Decimal, decimal_adapter)
    return renderer
Пример #8
0
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
Пример #9
0
def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    # setup the database engine
    engine = engine_from_config(settings, 'sqlalchemy.', pool_size=5)
    sqlahelper.add_engine(engine)

    # initialize database structures
    initialize_db(engine)

    # set up beaker cache
    set_cache_regions_from_settings(settings)

    config = Configurator(settings=settings, root_factory=ACLFactory)

    # mako for templating
    config.include('pyramid_mako')

    # Mozilla Persona as the login verifier. It defines default
    # authentication and authorization policies.
    config.include('pyramid_persona')

    # override the authn policy to provide a callback
    secret = settings.get('persona.secret', None)
    authn_policy = AuthTktAuthenticationPolicy(secret, callback=groupfinder, hashalg='sha512')
    config.set_authentication_policy(authn_policy)

    # for json-encoded responses
    def datetime_timedelta_adapter(obj, request):
        return obj.seconds;
    def datetime_datetime_adapter(obj, request):
        return obj.isoformat();
    def decimal_adapter(obj, request):
        return float(obj);
    jsonp = JSONP(param_name='callback')
    jsonp.add_adapter(datetime.timedelta, datetime_timedelta_adapter)
    jsonp.add_adapter(datetime.datetime, datetime_datetime_adapter)
    jsonp.add_adapter(Decimal, decimal_adapter)
    config.add_renderer('jsonp', jsonp)

    # for static assets
    config.add_static_view('static', 'xonstat:static')

    # robots
    config.add_route("robots", "robots.txt")
    config.add_view(robots, route_name="robots")

    # for 404s
    config.add_view(notfound, context=HTTPNotFound, renderer="404.mako")

    # ROOT ROUTE
    config.add_route("main_index", "/")
    config.add_view(main_index, route_name="main_index", renderer="main_index.mako")

    config.add_route("cookies", "/cookies");
    config.add_view(cookie_policy, route_name="cookies", renderer="cookies.mako");

    config.add_route("recent_games_json", "/recentgames.json")
    config.add_view(recent_games_json, route_name="recent_games_json", renderer="jsonp")

    config.add_route("top_servers_json", "/topservers.json")
    config.add_view(top_servers_json, route_name="top_servers_json", renderer="jsonp")

    config.add_route("top_maps_json", "/topmaps.json")
    config.add_view(top_maps_json, route_name="top_maps_json", renderer="jsonp")

    config.add_route("news_index", "/news")
    config.add_view(news_index, route_name="news_index", renderer="news_index.mako")

    config.add_route("forum_index", "/forum")
    config.add_view(news_index, route_name="forum_index", renderer="news_index.mako")


    # MAIN SUBMISSION ROUTE
    config.add_route("submit_stats", "stats/submit")
    config.add_view(submit_stats, route_name="submit_stats", renderer="jsonp")

    # PLAYER ROUTES
    config.add_route("player_game_index",      "/player/{player_id:\d+}/games")
    config.add_view(player_game_index,      route_name="player_game_index",      renderer="player_game_index.mako")

    config.add_route("player_game_index_json", "/player/{player_id:\d+}/games.json")
    config.add_view(player_game_index_json, route_name="player_game_index_json", renderer="jsonp")

    config.add_route("player_info",      "/player/{id:\d+}")
    config.add_view(player_info,      route_name="player_info",      renderer="player_info.mako")

    config.add_route("player_info_json", "/player/{id:\d+}.json")
    config.add_view(player_info_json, route_name="player_info_json", renderer="jsonp")

    config.add_route("player_hashkey_info_text", "/player/me")
    config.add_view(player_hashkey_info_text, route_name="player_hashkey_info_text", renderer="player_hashkey_info_text.mako")

    config.add_route("player_hashkey_info_json", "/player/me.json")
    config.add_view(player_hashkey_info_json, route_name="player_hashkey_info_json", renderer="jsonp")

    config.add_route("player_elo_info_text", "/player/{hashkey}/elo.txt")
    config.add_view(player_elo_info_text, route_name="player_elo_info_text", renderer="player_elo_info_text.mako")

    config.add_route("players_elo", "/elo/{hashkeys}");
    config.add_view(players_elo, route_name="players_elo", renderer="jsonp")

    config.add_route("players_elo_b", "/elo_b/{hashkeys}");
    config.add_view(players_elo_b, route_name="players_elo_b", renderer="jsonp")

    config.add_route("players_glicko", "/glicko/{hashkeys}");
    config.add_view(players_glicko, route_name="players_glicko", renderer="jsonp")

    config.add_route("players_aliases_json", "/aliases/{hashkeys}.json");
    config.add_view(players_aliases_json, route_name="players_aliases_json", renderer="jsonp")
    config.add_route("players_aliases_text", "/aliases/{hashkeys}");
    config.add_view(players_aliases_text, route_name="players_aliases_text", renderer="players_aliases_text.mako")

    config.add_route("player_recent_games_json", "/player/{id:\d+}/recent_games.json");
    config.add_view(player_recent_games_json, route_name="player_recent_games_json", renderer="jsonp");


    # FIXME - needs an additional method to convert to JSON
    config.add_route("player_elo_info_json", "/player/{hashkey}/elo.json")
    config.add_view(player_elo_info_json, route_name="player_elo_info_json", renderer="jsonp")

    config.add_route("player_accuracy",      "/player/{id:\d+}/accuracy")
    config.add_view(player_accuracy_json, route_name="player_accuracy",      renderer="jsonp")

    config.add_route("player_index",      "/players")
    config.add_view(player_index,      route_name="player_index",      renderer="player_index.mako")

    config.add_route("player_index_json", "/players.json")
    config.add_view(player_index_json, route_name="player_index_json", renderer="jsonp")

    config.add_route("player_captimes",      "/player/{player_id:\d+}/captimes")
    config.add_view(player_captimes,      route_name="player_captimes",      renderer="player_captimes.mako")

    config.add_route("player_captimes_json", "/player/{player_id:\d+}/captimes.json")
    config.add_view(player_captimes_json, route_name="player_captimes_json", renderer="jsonp")

    config.add_route("player_weaponstats_data_json", "/player/{id:\d+}/weaponstats.json")
    config.add_view(player_weaponstats_data_json, route_name="player_weaponstats_data_json", renderer="jsonp")

    config.add_route("top_players_by_time", "/topactive")
    config.add_view(top_players_by_time, route_name="top_players_by_time", renderer="top_players_by_time.mako")

    config.add_route("top_servers_by_players", "/topservers")
    config.add_view(top_servers_by_players, route_name="top_servers_by_players", renderer="top_servers_by_players.mako")

    config.add_route("top_maps_by_times_played", "/topmaps")
    config.add_view(top_maps_by_times_played, route_name="top_maps_by_times_played", renderer="top_maps_by_times_played.mako")

    # GAME ROUTES
    config.add_route("game_info",      "/game/{id:\d+|[0-9a-fA-F]+-[0-9a-fA-F\-]+}")
    config.add_view(game_info,      route_name="game_info",      renderer="game_info.mako")

    config.add_route("game_info_json", "/game/{id:\d+}.json")
    config.add_view(game_info_json, route_name="game_info_json", renderer="jsonp")

    config.add_route("rank_index0",      "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}")
    config.add_view(rank_index,      route_name="rank_index0",      renderer="rank_index.mako")
    config.add_route("rank_index",     "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}/{region:\d+}")
    config.add_view(rank_index,      route_name="rank_index",      renderer="rank_index.mako")

    config.add_route("rank_index_json0", "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}.json")
    config.add_view(rank_index_json, route_name="rank_index_json0", renderer="jsonp")
    config.add_route("rank_index_json", "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}/{region:\d+}.json")
    config.add_view(rank_index_json, route_name="rank_index_json", renderer="jsonp")

    config.add_route("game_index", "/games")
    config.add_view(game_finder, route_name="game_index", renderer="game_finder.mako")

    # SERVER ROUTES
    config.add_route("server_index",      "/servers")
    config.add_view(server_index,      route_name="server_index",      renderer="server_index.mako")

    config.add_route("server_index_json", "/servers.json")
    config.add_view(server_index_json, route_name="server_index_json", renderer="jsonp")

    config.add_route("server_game_index",      "/server/{server_id:\d+}/games/page/{page:\d+}")
    config.add_view(server_game_index,      route_name="server_game_index",      renderer="server_game_index.mako")

    config.add_route("server_game_index_json", "/server/{server_id:\d+}/games.json")
    config.add_view(server_game_index_json, route_name="server_game_index_json", renderer="jsonp")

    config.add_route("server_info",      "/server/{id:\d+|.+\..+:\d+}")
    config.add_view(server_info,      route_name="server_info",      renderer="server_info.mako")

    config.add_route("server_info_json", "/server/{id:\d+|.+\..+:\d+}.json")
    config.add_view(server_info_json, route_name="server_info_json", renderer="jsonp")

    # MAP ROUTES
    config.add_route("map_index",      "/maps")
    config.add_view(map_index,      route_name="map_index",      renderer="map_index.mako")

    config.add_route("map_index_json", "/maps.json")
    config.add_view(map_index_json, route_name="map_index_json", renderer="jsonp")

    config.add_route("map_info",      "/map/{id}")
    config.add_view(map_info,      route_name="map_info",      renderer="map_info.mako")

    config.add_route("map_info_json", "/map/{id:\d+}.json")
    config.add_view(map_info_json, route_name="map_info_json", renderer="jsonp")

    config.add_route("map_captimes",      "/map/{id:\d+}/captimes")
    config.add_view(map_captimes,      route_name="map_captimes",      renderer="map_captimes.mako")

    config.add_route("map_captimes_json", "/map/{id:\d+}/captimes.json")
    config.add_view(map_captimes_json, route_name="map_captimes_json", renderer="jsonp")

    # SEARCH ROUTES
    config.add_route("search",      "search")
    config.add_view(search,      route_name="search",      renderer="search.mako")

    config.add_route("search_json", "search.json")
    config.add_view(search_json, route_name="search_json", renderer="jsonp")

    # ADMIN ROUTES
    config.add_forbidden_view(forbidden, renderer="forbidden.mako")

    config.add_route("login", "/login")
    config.add_view(login, route_name="login", check_csrf=True, renderer="json")

    config.add_route("merge", "/admin/merge")
    config.add_view(merge, route_name="merge", renderer="merge.mako", permission="merge")

    return config.make_wsgi_app()
Пример #10
0
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
Пример #11
0
def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    # setup the database engine
    engine = engine_from_config(settings, 'sqlalchemy.', pool_size=5)
    sqlahelper.add_engine(engine)

    # initialize database structures
    initialize_db(engine)

    # set up beaker cache
    set_cache_regions_from_settings(settings)

    config = Configurator(settings=settings, root_factory=ACLFactory)

    # mako for templating
    config.include('pyramid_mako')

    # Mozilla Persona as the login verifier. It defines default
    # authentication and authorization policies.
    config.include('pyramid_persona')

    # override the authn policy to provide a callback
    secret = settings.get('persona.secret', None)
    authn_policy = AuthTktAuthenticationPolicy(secret,
                                               callback=groupfinder,
                                               hashalg='sha512')
    config.set_authentication_policy(authn_policy)

    # for json-encoded responses
    def datetime_timedelta_adapter(obj, request):
        return obj.seconds

    def datetime_datetime_adapter(obj, request):
        return obj.isoformat()

    def decimal_adapter(obj, request):
        return float(obj)

    jsonp = JSONP(param_name='callback')
    jsonp.add_adapter(datetime.timedelta, datetime_timedelta_adapter)
    jsonp.add_adapter(datetime.datetime, datetime_datetime_adapter)
    jsonp.add_adapter(Decimal, decimal_adapter)
    config.add_renderer('jsonp', jsonp)

    # for static assets
    config.add_static_view('static', 'xonstat:static')

    # robots
    config.add_route("robots", "robots.txt")
    config.add_view(robots, route_name="robots")

    # for 404s
    config.add_view(notfound, context=HTTPNotFound, renderer="404.mako")

    # ROOT ROUTE
    config.add_route("main_index", "/")
    config.add_view(main_index,
                    route_name="main_index",
                    renderer="main_index.mako")

    config.add_route("cookies", "/cookies")
    config.add_view(cookie_policy,
                    route_name="cookies",
                    renderer="cookies.mako")

    config.add_route("recent_games_json", "/recentgames.json")
    config.add_view(recent_games_json,
                    route_name="recent_games_json",
                    renderer="jsonp")

    config.add_route("top_servers_json", "/topservers.json")
    config.add_view(top_servers_json,
                    route_name="top_servers_json",
                    renderer="jsonp")

    config.add_route("top_maps_json", "/topmaps.json")
    config.add_view(top_maps_json,
                    route_name="top_maps_json",
                    renderer="jsonp")

    config.add_route("news_index", "/news")
    config.add_view(news_index,
                    route_name="news_index",
                    renderer="news_index.mako")

    config.add_route("forum_index", "/forum")
    config.add_view(news_index,
                    route_name="forum_index",
                    renderer="news_index.mako")

    # MAIN SUBMISSION ROUTE
    config.add_route("submit_stats", "stats/submit")
    config.add_view(submit_stats, route_name="submit_stats", renderer="jsonp")

    # PLAYER ROUTES
    config.add_route("player_game_index", "/player/{player_id:\d+}/games")
    config.add_view(player_game_index,
                    route_name="player_game_index",
                    renderer="player_game_index.mako")

    config.add_route("player_game_index_json",
                     "/player/{player_id:\d+}/games.json")
    config.add_view(player_game_index_json,
                    route_name="player_game_index_json",
                    renderer="jsonp")

    config.add_route("player_info", "/player/{id:\d+}")
    config.add_view(player_info,
                    route_name="player_info",
                    renderer="player_info.mako")

    config.add_route("player_info_json", "/player/{id:\d+}.json")
    config.add_view(player_info_json,
                    route_name="player_info_json",
                    renderer="jsonp")

    config.add_route("player_hashkey_info_text", "/player/me")
    config.add_view(player_hashkey_info_text,
                    route_name="player_hashkey_info_text",
                    renderer="player_hashkey_info_text.mako")

    config.add_route("player_hashkey_info_json", "/player/me.json")
    config.add_view(player_hashkey_info_json,
                    route_name="player_hashkey_info_json",
                    renderer="jsonp")

    config.add_route("player_elo_info_text", "/player/{hashkey}/elo.txt")
    config.add_view(player_elo_info_text,
                    route_name="player_elo_info_text",
                    renderer="player_elo_info_text.mako")

    config.add_route("players_elo", "/elo/{hashkeys}")
    config.add_view(players_elo, route_name="players_elo", renderer="jsonp")

    config.add_route("players_elo_b", "/elo_b/{hashkeys}")
    config.add_view(players_elo_b,
                    route_name="players_elo_b",
                    renderer="jsonp")

    config.add_route("players_glicko", "/glicko/{hashkeys}")
    config.add_view(players_glicko,
                    route_name="players_glicko",
                    renderer="jsonp")

    config.add_route("players_aliases_json", "/aliases/{hashkeys}.json")
    config.add_view(players_aliases_json,
                    route_name="players_aliases_json",
                    renderer="jsonp")
    config.add_route("players_aliases_text", "/aliases/{hashkeys}")
    config.add_view(players_aliases_text,
                    route_name="players_aliases_text",
                    renderer="players_aliases_text.mako")

    config.add_route("player_recent_games_json",
                     "/player/{id:\d+}/recent_games.json")
    config.add_view(player_recent_games_json,
                    route_name="player_recent_games_json",
                    renderer="jsonp")

    # FIXME - needs an additional method to convert to JSON
    config.add_route("player_elo_info_json", "/player/{hashkey}/elo.json")
    config.add_view(player_elo_info_json,
                    route_name="player_elo_info_json",
                    renderer="jsonp")

    config.add_route("player_accuracy", "/player/{id:\d+}/accuracy")
    config.add_view(player_accuracy_json,
                    route_name="player_accuracy",
                    renderer="jsonp")

    config.add_route("player_index", "/players")
    config.add_view(player_index,
                    route_name="player_index",
                    renderer="player_index.mako")

    config.add_route("player_index_json", "/players.json")
    config.add_view(player_index_json,
                    route_name="player_index_json",
                    renderer="jsonp")

    config.add_route("player_captimes", "/player/{player_id:\d+}/captimes")
    config.add_view(player_captimes,
                    route_name="player_captimes",
                    renderer="player_captimes.mako")

    config.add_route("player_captimes_json",
                     "/player/{player_id:\d+}/captimes.json")
    config.add_view(player_captimes_json,
                    route_name="player_captimes_json",
                    renderer="jsonp")

    config.add_route("player_weaponstats_data_json",
                     "/player/{id:\d+}/weaponstats.json")
    config.add_view(player_weaponstats_data_json,
                    route_name="player_weaponstats_data_json",
                    renderer="jsonp")

    config.add_route("top_players_by_time", "/topactive")
    config.add_view(top_players_by_time,
                    route_name="top_players_by_time",
                    renderer="top_players_by_time.mako")

    config.add_route("top_servers_by_players", "/topservers")
    config.add_view(top_servers_by_players,
                    route_name="top_servers_by_players",
                    renderer="top_servers_by_players.mako")

    config.add_route("top_maps_by_times_played", "/topmaps")
    config.add_view(top_maps_by_times_played,
                    route_name="top_maps_by_times_played",
                    renderer="top_maps_by_times_played.mako")

    # GAME ROUTES
    config.add_route("game_info", "/game/{id:\d+|[0-9a-fA-F]+-[0-9a-fA-F\-]+}")
    config.add_view(game_info,
                    route_name="game_info",
                    renderer="game_info.mako")

    config.add_route("game_info_json", "/game/{id:\d+}.json")
    config.add_view(game_info_json,
                    route_name="game_info_json",
                    renderer="jsonp")

    config.add_route(
        "rank_index0",
        "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}")
    config.add_view(rank_index,
                    route_name="rank_index0",
                    renderer="rank_index.mako")
    config.add_route(
        "rank_index",
        "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}/{region:\d+}")
    config.add_view(rank_index,
                    route_name="rank_index",
                    renderer="rank_index.mako")

    config.add_route(
        "rank_index_json0",
        "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}.json")
    config.add_view(rank_index_json,
                    route_name="rank_index_json0",
                    renderer="jsonp")
    config.add_route(
        "rank_index_json",
        "/ranks/{game_type_cd:ctf|ffa|tdm|duel|ca|ft|race|rr|ad}/{region:\d+}.json"
    )
    config.add_view(rank_index_json,
                    route_name="rank_index_json",
                    renderer="jsonp")

    config.add_route("game_index", "/games")
    config.add_view(game_finder,
                    route_name="game_index",
                    renderer="game_finder.mako")

    # SERVER ROUTES
    config.add_route("server_index", "/servers")
    config.add_view(server_index,
                    route_name="server_index",
                    renderer="server_index.mako")

    config.add_route("server_index_json", "/servers.json")
    config.add_view(server_index_json,
                    route_name="server_index_json",
                    renderer="jsonp")

    config.add_route("server_game_index",
                     "/server/{server_id:\d+}/games/page/{page:\d+}")
    config.add_view(server_game_index,
                    route_name="server_game_index",
                    renderer="server_game_index.mako")

    config.add_route("server_game_index_json",
                     "/server/{server_id:\d+}/games.json")
    config.add_view(server_game_index_json,
                    route_name="server_game_index_json",
                    renderer="jsonp")

    config.add_route("server_info", "/server/{id:\d+|.+\..+:\d+}")
    config.add_view(server_info,
                    route_name="server_info",
                    renderer="server_info.mako")

    config.add_route("server_info_json", "/server/{id:\d+|.+\..+:\d+}.json")
    config.add_view(server_info_json,
                    route_name="server_info_json",
                    renderer="jsonp")

    # MAP ROUTES
    config.add_route("map_index", "/maps")
    config.add_view(map_index,
                    route_name="map_index",
                    renderer="map_index.mako")

    config.add_route("map_index_json", "/maps.json")
    config.add_view(map_index_json,
                    route_name="map_index_json",
                    renderer="jsonp")

    config.add_route("map_info", "/map/{id}")
    config.add_view(map_info, route_name="map_info", renderer="map_info.mako")

    config.add_route("map_info_json", "/map/{id:\d+}.json")
    config.add_view(map_info_json,
                    route_name="map_info_json",
                    renderer="jsonp")

    config.add_route("map_captimes", "/map/{id:\d+}/captimes")
    config.add_view(map_captimes,
                    route_name="map_captimes",
                    renderer="map_captimes.mako")

    config.add_route("map_captimes_json", "/map/{id:\d+}/captimes.json")
    config.add_view(map_captimes_json,
                    route_name="map_captimes_json",
                    renderer="jsonp")

    # SEARCH ROUTES
    config.add_route("search", "search")
    config.add_view(search, route_name="search", renderer="search.mako")

    config.add_route("search_json", "search.json")
    config.add_view(search_json, route_name="search_json", renderer="jsonp")

    # ADMIN ROUTES
    config.add_forbidden_view(forbidden, renderer="forbidden.mako")

    config.add_route("login", "/login")
    config.add_view(login,
                    route_name="login",
                    check_csrf=True,
                    renderer="json")

    config.add_route("merge", "/admin/merge")
    config.add_view(merge,
                    route_name="merge",
                    renderer="merge.mako",
                    permission="merge")

    return config.make_wsgi_app()
Пример #12
0
    objects, such as datetime and colander.null we solve it here.
    """
    class Encoder(json.JSONEncoder):
        def default(self, obj):
            """Convert ``obj`` to something JSON encoder can handle."""
            # if isinstance(obj, NamedTuple):
            #     obj = dict((k, getattr(obj, k)) for k in obj.keys())
            if isinstance(obj, decimal.Decimal):
                return str(obj)
            elif isinstance(obj, datetime_types):
                return str(obj)
            elif obj is colander.null:
                return None

            return basedefault(obj)

    return Encoder


def to_json(obj, default=None, **kw):
    return json.dumps(obj, cls=_encoder(default), **kw)


jsonp = JSONP(param_name='callback', serializer=to_json)
jsonp.add_adapter(Content, serialize)


def includeme(config):
    config.add_renderer('kotti_jsonp', jsonp)
    config.scan(__name__)