~launchpad-pqm/launchpad/devel

8687.15.17 by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/.
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4983.1.1 by Curtis Hovey
Added lint exceptions to __init__.py and interface/*.py.
4
# pylint: disable-msg=E0211,E0213
3691.59.8 by Stuart Bishop
Add PillarSet
5
6
"""Launchpad Pillars share a namespace.
7
10724.1.2 by Henning Eggers
Second batch done.
8
Pillars are currently Product, ProjectGroup and Distribution.
3691.59.8 by Stuart Bishop
Add PillarSet
9
"""
10
11
__metaclass__ = type
12
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
13
from lazr.restful.declarations import (
14
    export_as_webservice_entry,
15
    export_read_operation,
16
    exported,
17
    operation_parameters,
18
    operation_returns_collection_of,
19
    )
20
from lazr.restful.fields import (
21
    CollectionField,
22
    Reference,
23
    )
24
from zope.interface import (
25
    Attribute,
26
    Interface,
27
    )
28
from zope.schema import (
29
    Bool,
30
    Int,
31
    List,
32
    TextLine,
33
    )
3691.59.8 by Stuart Bishop
Add PillarSet
34
3691.59.9 by Stuart Bishop
Pillar name validators and test fixes
35
from canonical.launchpad import _
5127.4.1 by Guilherme Salgado
Allos users to Register a product while adding an upstream task
36
37
7245.2.6 by Guilherme Salgado
Move aliases stuff from IPillar to IHasAliases
38
__all__ = ['IHasAliases', 'IPillar', 'IPillarName', 'IPillarNameSet']
6080.9.8 by Edwin Grubbs
Added IPillar interface and security
39
40
41
class IPillar(Interface):
6989.2.9 by Leonard Richardson
Added docstrings.
42
    """An object that might be a project, a project group, or a distribution.
43
44
    This is a polymorphic object served by the pillar set. Check the
45
    individual object to see what type it is.
46
    """
6989.2.2 by Leonard Richardson
Exposed named operations.
47
    export_as_webservice_entry()
6789.15.3 by Edwin Grubbs
Exported IPillar
48
    active = exported(
49
        Bool(title=_('Active'),
50
             description=_("Whether or not this item is active.")))
7245.2.6 by Guilherme Salgado
Move aliases stuff from IPillar to IHasAliases
51
52
53
class IHasAliases(Interface):
54
7245.2.3 by Guilherme Salgado
New .aliases and .setAliases() for IPillar, with implementations on Distribution, Project and Product, all requiring launchpad.Admin for setAliases(). Also make it possible to search and look up pillars by their aliases
55
    aliases = List(
7245.2.7 by Guilherme Salgado
A couple changes as per Edwin's suggestion
56
        title=_('Aliases'), required=False, readonly=True,
7245.2.3 by Guilherme Salgado
New .aliases and .setAliases() for IPillar, with implementations on Distribution, Project and Product, all requiring launchpad.Admin for setAliases(). Also make it possible to search and look up pillars by their aliases
57
        description=_(
58
            "The names (as strings) which are aliases to this pillar."))
59
7245.2.8 by Guilherme Salgado
A couple more changes suggested by Edwin
60
    # Instead of a method for setting aliases we could make the 'aliases'
61
    # attribute writable, but we decided to go with a method because this
62
    # operation may trigger several inserts/deletes in the database and a
63
    # method helps clarifying it may be an expensive operation.
7245.2.3 by Guilherme Salgado
New .aliases and .setAliases() for IPillar, with implementations on Distribution, Project and Product, all requiring launchpad.Admin for setAliases(). Also make it possible to search and look up pillars by their aliases
64
    def setAliases(names):
65
        """Set the given names as this pillar's aliases.
66
67
        For each of the given names, check that it's not already in use by
68
        another pillar and then make sure it exists as an alias for this
69
        pillar.  If the given names don't include any of this pillar's
70
        existing aliases, these are deleted.
71
72
        :param names: A sequence of names (as strings) that should be aliases
73
            to this pillar.
74
        """
3691.237.1 by Stuart Bishop
Pillar vocabularies and rename IPillarSet to match underlying database table name
75
76
77
class IPillarName(Interface):
6989.2.9 by Leonard Richardson
Added docstrings.
78
    """A data structure for identifying a pillar.
79
80
    This includes the pillar object, as well as information about whether
81
    it's a project, project group, or distribution.
82
    """
3691.237.1 by Stuart Bishop
Pillar vocabularies and rename IPillarSet to match underlying database table name
83
    id = Int(title=_('The PillarName ID'))
6989.2.1 by Leonard Richardson
Initial attempt at implementation.
84
    name = TextLine(title=u"The name.")
3691.237.1 by Stuart Bishop
Pillar vocabularies and rename IPillarSet to match underlying database table name
85
    product = Attribute('The project that has this name, or None')
86
    project = Attribute('The project that has this name, or None')
87
    distribution = Attribute('The distribution that has this name, or None')
3691.237.4 by Stuart Bishop
Pillar vocabularies should filter deactivated rows
88
    active = Attribute('The pillar is active')
4308.1.1 by Diogo Matsubara
Fix bug 1135 (No obvious way to get from a person/team to what projects/products they're involved in
89
    pillar = Attribute('The pillar object')
3691.237.1 by Stuart Bishop
Pillar vocabularies and rename IPillarSet to match underlying database table name
90
91
92
class IPillarNameSet(Interface):
6989.2.7 by Leonard Richardson
Added docstring.
93
    """An object for searching across projects, project groups, and distros.
94
6989.2.9 by Leonard Richardson
Added docstrings.
95
    Projects, project groups, and distributions are collectively known as
6989.2.7 by Leonard Richardson
Added docstring.
96
    "pillars". This object lets you do a combined search across all
97
    types of pillars. It also gives you access to pillars that have
98
    been flagged by administrators as "featured" pillars.
99
    """
6989.2.2 by Leonard Richardson
Exposed named operations.
100
    export_as_webservice_entry('pillars')
6989.2.1 by Leonard Richardson
Initial attempt at implementation.
101
3691.59.8 by Stuart Bishop
Add PillarSet
102
    def __contains__(name):
7245.2.3 by Guilherme Salgado
New .aliases and .setAliases() for IPillar, with implementations on Distribution, Project and Product, all requiring launchpad.Admin for setAliases(). Also make it possible to search and look up pillars by their aliases
103
        """True if the given name is an active Pillar or an alias to one."""
3691.59.8 by Stuart Bishop
Add PillarSet
104
105
    def __getitem__(name):
7245.2.3 by Guilherme Salgado
New .aliases and .setAliases() for IPillar, with implementations on Distribution, Project and Product, all requiring launchpad.Admin for setAliases(). Also make it possible to search and look up pillars by their aliases
106
        """Get an active pillar by its name or any of its aliases.
3691.336.17 by Guilherme Salgado
Fix bugs 85433 and 85432, about inactive products/projects
107
108
        If there's no pillar with the given name or there is one but it's
109
        inactive, raise NotFoundError.
110
        """
111
112
    def getByName(name, ignore_inactive=False):
7245.2.3 by Guilherme Salgado
New .aliases and .setAliases() for IPillar, with implementations on Distribution, Project and Product, all requiring launchpad.Admin for setAliases(). Also make it possible to search and look up pillars by their aliases
113
        """Return the pillar whose name or alias matches the given name.
3691.336.17 by Guilherme Salgado
Fix bugs 85433 and 85432, about inactive products/projects
114
115
        If ignore_inactive is True, then only active pillars are considered.
116
117
        If no pillar is found, return None.
118
        """
3691.59.8 by Stuart Bishop
Add PillarSet
119
3847.2.88 by Mark Shuttleworth
Better mugshots and buttons, and a fix for project searching
120
    def count_search_matches(text):
121
        """Return the total number of Pillars matching :text:"""
122
6989.2.2 by Leonard Richardson
Exposed named operations.
123
124
    @operation_parameters(text=TextLine(title=u"Search text"),
125
                          limit=Int(title=u"Maximum number of items to "
126
                                    "return. This is a hard limit: any "
127
                                    "pagination you request will happen "
128
                                    "within this limit.",
129
                                    required=False))
130
    @operation_returns_collection_of(IPillar)
131
    @export_read_operation()
3691.270.7 by Guilherme Salgado
Some shanges requested by Francis.
132
    def search(text, limit):
6989.2.7 by Leonard Richardson
Added docstring.
133
        """Return Projects/Project groups/Distros matching :text:.
134
135
        If :limit: is None, the default batch size will be used.
3691.270.1 by Guilherme Salgado
New PillarSet.search() which searches across Products, Distributions and Projects
136
137
        The results are ordered descending by rank.
138
        """
139
5323.2.1 by Mark Shuttleworth
Manage featured projects in the db
140
    def add_featured_project(project):
141
        """Add a project to the featured project list."""
142
143
    def remove_featured_project(project):
144
        """Remove a project from the featured project list."""
145
6989.2.1 by Leonard Richardson
Initial attempt at implementation.
146
    featured_projects = exported(
147
        CollectionField(
148
            title=_('Projects, project groups, and distributions that are '
149
                    'featured on the site.'),
6989.2.2 by Leonard Richardson
Exposed named operations.
150
            value_type=Reference(schema=IPillar)),
151
        exported_as="featured_pillars"
6989.2.1 by Leonard Richardson
Initial attempt at implementation.
152
        )