~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
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""Browser code for Distro Series Languages."""

__metaclass__ = type

__all__ = [
    'DistroSeriesLanguageNavigation',
    'DistroSeriesLanguageView',
    'ProductSeriesLanguageNavigation',
    'ProductSeriesLanguageView',
    ]

from canonical.launchpad.readonly import is_read_only
from canonical.launchpad.webapp import LaunchpadView
from canonical.launchpad.webapp.batching import BatchNavigator
from canonical.launchpad.webapp.publisher import Navigation
from lp.app.browser.tales import PersonFormatterAPI
from lp.registry.model.sourcepackagename import SourcePackageName
from lp.services.database.bulk import load_related
from lp.services.propertycache import cachedproperty
from lp.translations.enums import TranslationPermission
from lp.translations.interfaces.distroserieslanguage import (
    IDistroSeriesLanguage,
    )
from lp.translations.interfaces.productserieslanguage import (
    IProductSeriesLanguage,
    )
from lp.translations.interfaces.translationsperson import ITranslationsPerson


class BaseSeriesLanguageView(LaunchpadView):
    """View base class to render translation status for an
    `IDistroSeries` and `IProductSeries`

    This class should not be directly instantiated.
    """

    pofiles = None
    label = "Translatable templates"
    series = None
    parent = None
    translationgroup = None

    def initialize(self, series, translationgroup):
        self.series = series
        self.translationgroup = translationgroup
        self.form = self.request.form

        if IDistroSeriesLanguage.providedBy(self.context):
            self.batchnav = BatchNavigator(
                self.series.getCurrentTranslationTemplates(),
                self.request)
            self.pofiles = self.context.getPOFilesFor(
                self.batchnav.currentBatch())
            load_related(
                SourcePackageName, self.batchnav.currentBatch(),
                ['sourcepackagenameID'])
        else:
            self.batchnav = BatchNavigator(self.context.pofiles, self.request)
            self.pofiles = self.batchnav.currentBatch()

    @property
    def translation_group(self):
        """Return the translation group for these translations.

        Return None if there's no translation group for them.
        """
        return self.translationgroup

    @cachedproperty
    def translation_team(self):
        """Return the translation team for these translations.

        Return None if there's no translation team for them.
        """
        if self.translation_group is not None:
            team = self.translation_group.query_translator(
                self.context.language)
        else:
            team = None
        return team

    @property
    def access_level_description(self):
        """Must not be called when there's no translation group."""

        if is_read_only():
            return (
                "No work can be done on these translations while Launchpad "
                "is in read-only mode.")

        if self.user is None:
            return ("You are not logged in. Please log in to work "
                    "on translations.")

        translations_person = ITranslationsPerson(self.user)
        translations_contact_link = None

        if self.translation_team:
            translations_contact_link = PersonFormatterAPI(
                self.translation_team.translator).link(None)
        elif self.translation_group:
            translations_contact_link = PersonFormatterAPI(
                self.translation_group.owner).link(None)
        else:
            assert self.translation_group is not None, (
                "Must not be called when there's no translation group.")

        if not translations_person.translations_relicensing_agreement:
            translation_license_url = PersonFormatterAPI(
                self.user).url(
                    view_name='+licensing',
                    rootsite='translations')
            return ("To make translations in Launchpad you need to "
                    "agree with the "
                    "<a href='%s'>Translations licensing</a>.") % (
                        translation_license_url)

        if len(self.pofiles) > 0:
            sample_pofile = self.pofiles[0]
            if sample_pofile.canEditTranslations(self.user):
                return "You can add and review translations."

            if sample_pofile.canAddSuggestions(self.user):
                return ("Your suggestions will be held for review by "
                        "%s. If you need help, or your translations are "
                        "not being reviewed, please get in touch with "
                        "%s.") % (
                            translations_contact_link,
                            translations_contact_link)

            permission = sample_pofile.translationpermission
            if permission == TranslationPermission.CLOSED:
                return ("These templates can be translated only by "
                        "their managers.")

        if self.translation_team is None:
            return ("Since there is nobody to manage translation "
                    "approvals into this language, you cannot add "
                    "new suggestions. If you are interested in making "
                    "translations, please contact %s.") % (
                        translations_contact_link)

        raise AssertionError(
            "BUG! Couldn't identify the user's access level for these "
            "translations.")


class DistroSeriesLanguageView(BaseSeriesLanguageView):
    """View class to render translation status for an `IDistroSeries`."""

    def initialize(self):
        series = self.context.distroseries
        super(DistroSeriesLanguageView, self).initialize(
            series=series,
            translationgroup=series.distribution.translationgroup)
        self.parent = self.series.distribution


class ProductSeriesLanguageView(BaseSeriesLanguageView):
    """View class to render translation status for an `IProductSeries`."""

    def initialize(self):
        series = self.context.productseries
        super(ProductSeriesLanguageView, self).initialize(
            series=series,
            translationgroup=series.product.translationgroup)
        self.context.recalculateCounts()
        self.parent = self.series.product


class DistroSeriesLanguageNavigation(Navigation):
    """Navigation for `IDistroSeriesLanguage`."""
    usedfor = IDistroSeriesLanguage


class ProductSeriesLanguageNavigation(Navigation):
    """Navigation for `IProductSeriesLanguage`."""
    usedfor = IProductSeriesLanguage