-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathext.py
84 lines (66 loc) · 2.78 KB
/
ext.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2017-2018 CERN.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
"""Cache module for Invenio."""
from __future__ import absolute_import, print_function
import pkg_resources
from flask_caching import Cache
from werkzeug.utils import import_string
from . import config
from ._compat import string_types
class InvenioCache(object):
"""Invenio-Cache extension."""
def __init__(self, app=None):
"""Extension initialization."""
if app:
self.init_app(app)
def init_app(self, app):
"""Flask application initialization."""
self.init_config(app)
self.cache = Cache(app)
self.is_authenticated_callback = _callback_factory(
app.config["CACHE_IS_AUTHENTICATED_CALLBACK"]
)
app.extensions["invenio-cache"] = self
def build_redis_url(self, app, db=0):
"""Return the redis connection string if configured or build it from its parts.
If set, then ``CACHE_REDIS_URL`` will be returned.
Otherwise, the URI will be pieced together by the configuration items
``KV_CACHE_{PASSWORD,HOST,PORT,NAME,PROTOCOL}``.
If that cannot be done (e.g. because required values are missing), then
``None`` will be returned.
Note: see: https://docs.celeryq.dev/en/stable/userguide/configuration.html#new-lowercase-settings
"""
if url := app.config.get("CACHE_REDIS_URL", None):
return url
params = {}
for config_name in ["HOST", "PORT", "PASSWORD", "PROTOCOL"]:
params[config_name] = app.config.get(f"KV_CACHE_{config_name}", None)
if params.get("HOST") and params.get("PORT"):
protocol = params.get("PROTOCOL", "redis")
password = f":{params['PASSWORD']}@" if params.get("PASSWORD") else ""
cache_url = f"{protocol}://{password}{params['HOST']}:{params['PORT']}/{db}"
return cache_url
return None
def init_config(self, app):
"""Initialize configuration."""
for k in dir(config):
if k.startswith("CACHE_"):
app.config.setdefault(k, getattr(config, k))
def _callback_factory(callback_imp):
"""Factory for creating a is authenticated callback."""
if callback_imp is None:
try:
pkg_resources.get_distribution("flask-login")
from flask_login import current_user
return lambda: current_user.is_authenticated
except pkg_resources.DistributionNotFound:
return lambda: False
elif isinstance(callback_imp, string_types):
return import_string(callback_imp)
else:
return callback_imp