Как получить путь к файлу add_static_view () в Пирамиде - PullRequest
2 голосов
/ 15 февраля 2012

Когда я добавляю static view, как это:

cfg = config.Configurator(...)
cfg.add_static_view(name='static', path='MyPgk:static')

# And I want to add a view for 'favicon.ico'.
cfg.add_route(name='favicon', pattern='/favicon.ico')
cfg.add_view(route_name='favicon', view='MyPgk.views.mymodule.favicon_view')

Я пытаюсь добавить раздражающий путь по умолчанию favicon.ico, равный /favicon.ico, который вызывается браузером, если он не определен на веб-странице. Я хотел бы использовать пример на http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/files.html и изменить его на:

def favicon_view(request, cache=dict()):
    if (not cache):
        _path_to_MyPkg_static = __WHAT_GOES_HERE__
        _icon = open(os.path.join(_path_to_MyPkg_static, 'favicon.ico')).read()
        cache['response'] = Response(content_type='image/x-icon', body=_icon)
    return cache['response']

Поскольку я не могу действительно определить _here, предложенный в примере, как я могу сделать его зависимым от request, чтобы получить фактический полный путь во время выполнения? Или я действительно должен иметь дело с:

_here = os.path.dirname(__file__)
_path_to_MyPkg_static = os.path.join(os.path.dirname(_here), 'static')

и необходимость быть осторожным, когда я решу провести рефакторинг и поместить представление в другой pkg или подпакет или куда-либо еще?

Что-то эквивалентное request.static_path(), но вместо получения url path, фактически получить путь к каталогу:

request.static_file_path('static') -> /path/to/site-packages/MyPkg/static

Спасибо

1 Ответ

3 голосов
/ 15 февраля 2012

Вы можете использовать модуль pkg_resources для создания путей, относящихся к модулям Python (и, таким образом, не зависящих от модуля, который их получает).Например:

import pkg_resources
print pkg_resources.resource_filename('os.path', 'static/favicon.ico')
# 'C:\\Python27\\lib\\static\\favicon.ico'

Просто замените os.path тем модулем, который является родительским для ваших статических файлов.

РЕДАКТИРОВАТЬ : Если вам нужно запомнить это 'static' маршрут сопоставлен с 'MyPkg:static', тогда проще всего сохранить его в каком-то словаре в первую очередь:

STATIC_ROUTES = {'static': 'MyPkg:static'}
for name, path in STATIC_ROUTES.iteritems():
    cfg.add_static_view(name=name, path=path)

и затем просто получить путь:

static_path = STATIC_ROUTES['static']
package, relative_path = static_path.split(':')
icon_path = pkg_resources.resource_filename(
    package, os.path.join(relative_path, 'favicon.ico'))

Если это невозможно, хотя (например, у вас нет доступа к cfg объекту), вы можете получить этот путь, это довольно болезненно.Вот пример функции, которая использует недокументированные вызовы (и может измениться в будущих версиях Pyramid) и игнорирует некоторые дополнительные настройки (например, route_prefix переменная конфигурации):

def get_static_path(request, name):
    from pyramid.config.views import StaticURLInfo
    registrations = StaticURLInfo()._get_registrations(request.registry)
    if not name.endswith('/'):
        name = name + '/'
    route_name = '__%s' % name
    for _url, spec, reg_route_name in registrations:
        print ':', reg_route_name
        if reg_route_name == route_name:
            return spec

В вашем случае она должна работать следующим образом:

>>> get_static_path(request, 'static')
MyPkg:static/
...