~launchpad-pqm/launchpad/devel

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
# Copyright 2011 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""FeatureFlagApplication allows access to information about feature flags."""

__metaclass__ = type
__all__ = [
    'IFeatureFlagApplication',
    'FeatureFlagApplication',
    ]

from zope.component import getUtility
from zope.interface import implements

from canonical.launchpad.webapp.interfaces import ILaunchpadApplication
from lp.registry.interfaces.person import IPersonSet
from lp.services.features.flags import FeatureController
from lp.services.features.rulesource import StormFeatureRuleSource
from lp.services.features.scopes import (
    default_scopes,
    FixedScope,
    MultiScopeHandler,
    TeamScope,
    )


class IFeatureFlagApplication(ILaunchpadApplication):
    """Mailing lists application root."""

    def getFeatureFlag(flag_name, username=None, scopes=()):
        """Return the value of the given feature flag.

        :param flag_name: The name of the flag to query.
        :param username: If supplied, the name of a Person to use in
            evaluating the 'team:' scope.
        :param scopes: A list of scopes to consider active.  The 'default'
            scope is always considered to be active, and does not need to be
            included here.
        """


class FeatureFlagApplication:

    implements(IFeatureFlagApplication)

    def getFeatureFlag(self, flag_name, active_scopes=()):
        scopes = list(default_scopes)
        for scope_name in active_scopes:
            if scope_name.startswith('user:'):
                person = getUtility(IPersonSet).getByName(
                    scope_name[len('user:'):])
                if person is not None:
                    scopes.append(TeamScope(lambda: person))
            else:
                scopes.append(FixedScope(scope_name))
        flag_name = unicode(flag_name)
        controller = FeatureController(
            MultiScopeHandler(scopes).lookup, StormFeatureRuleSource())
        return controller.getFlag(flag_name)