示例#1
0
 def person_is_translator(self):
     """Is this person active in translations?"""
     if self.context.is_team:
         return False
     person = ITranslationsPerson(self.context)
     history = person.getTranslationHistory(self.history_horizon).any()
     return history is not None
示例#2
0
 def person_is_translator(self):
     """Is this person active in translations?"""
     if self.context.is_team:
         return False
     person = ITranslationsPerson(self.context)
     history = person.getTranslationHistory(self.history_horizon).any()
     return history is not None
示例#3
0
    def user_is_new_translator(self):
        """Is this user someone who has done no translation work yet?"""
        user = getUtility(ILaunchBag).user
        if user is not None:
            translationsperson = ITranslationsPerson(user)
            if not translationsperson.hasTranslated():
                return True

        return False
示例#4
0
 def test_skips_translation_relicensing_agreements(self):
     person = self.factory.makePerson()
     translations_person = ITranslationsPerson(person)
     translations_person.translations_relicensing_agreement = True
     person_id = person.id
     account_id = person.account.id
     script = self.makeScript([six.ensure_str(person.name)])
     with dbuser('launchpad'):
         self.runScript(script)
     self.assertRemoved(account_id, person_id)
     self.assertTrue(translations_person.translations_relicensing_agreement)
示例#5
0
    def _review_targets(self):
        """Query and aggregate the top targets for review.

        :return: a list of translation targets.  Multiple `POFile`s may be
            aggregated together into a single target.
        """
        person = ITranslationsPerson(self.context)
        pofiles = person.getReviewableTranslationFiles(
            no_older_than=self.history_horizon)

        return ReviewLinksAggregator().aggregate(pofiles)
示例#6
0
    def _review_targets(self):
        """Query and aggregate the top targets for review.

        :return: a list of translation targets.  Multiple `POFile`s may be
            aggregated together into a single target.
        """
        person = ITranslationsPerson(self.context)
        pofiles = person.getReviewableTranslationFiles(
            no_older_than=self.history_horizon)

        return ReviewLinksAggregator().aggregate(pofiles)
    def test_canTranslate(self):
        # A user who has declined the licensing agreement can't
        # translate.  Someone who has agreed, or not made a decision
        # yet, can.
        user = self.factory.makePerson()
        translations_user = ITranslationsPerson(user)

        self.assertTrue(self.policy._canTranslate(user))

        translations_user.translations_relicensing_agreement = True
        self.assertTrue(self.policy._canTranslate(user))

        translations_user.translations_relicensing_agreement = False
        self.assertFalse(self.policy._canTranslate(user))
示例#8
0
    def _getTargetsForTranslation(self, max_fetch=None):
        """Get translation targets for this person to translate.

        Results are ordered from most to fewest untranslated messages.
        """
        person = ITranslationsPerson(self.context)
        urgent_first = (max_fetch >= 0)
        pofiles = person.getTranslatableFiles(
            no_older_than=self.history_horizon, urgent_first=urgent_first)

        if max_fetch is not None:
            pofiles = pofiles[:abs(max_fetch)]

        return TranslateLinksAggregator().aggregate(pofiles)
    def test_canTranslate(self):
        # A user who has declined the licensing agreement can't
        # translate.  Someone who has agreed, or not made a decision
        # yet, can.
        user = self.factory.makePerson()
        translations_user = ITranslationsPerson(user)

        self.assertTrue(self.policy._canTranslate(user))

        translations_user.translations_relicensing_agreement = True
        self.assertTrue(self.policy._canTranslate(user))

        translations_user.translations_relicensing_agreement = False
        self.assertFalse(self.policy._canTranslate(user))
示例#10
0
    def _getTargetsForTranslation(self, max_fetch=None):
        """Get translation targets for this person to translate.

        Results are ordered from most to fewest untranslated messages.
        """
        person = ITranslationsPerson(self.context)
        urgent_first = (max_fetch >= 0)
        pofiles = person.getTranslatableFiles(
            no_older_than=self.history_horizon, urgent_first=urgent_first)

        if max_fetch is not None:
            pofiles = pofiles[:abs(max_fetch)]

        return TranslateLinksAggregator().aggregate(pofiles)
示例#11
0
    def initialize(self):
        self.pofile = self.context
        translations_person = ITranslationsPerson(self.user, None)
        if (self.user is not None and
            translations_person.translations_relicensing_agreement is None):
            url = str(self.request.URL).decode('US-ASCII', 'replace')
            if self.request.get('QUERY_STRING', None):
                url = url + '?' + self.request['QUERY_STRING']

            return self.request.response.redirect(
                canonical_url(self.user, view_name='+licensing',
                              rootsite='translations') +
                '?' + urllib.urlencode({'back_to': url}))

        # The handling of errors is slightly tricky here. Because this
        # form displays multiple POMsgSetViews, we need to track the
        # various errors individually. This dictionary is keyed on
        # POTMsgSet; it's a slightly unusual key value but it will be
        # useful for doing display of only widgets with errors when we
        # do that.
        self.errors = {}
        self.translationmessage_views = []
        # The batchnav's start should change when the user mutates a
        # filtered views of messages.
        self.start_offset = 0

        self._initializeShowOption()
        super(POFileTranslateView, self).initialize()
示例#12
0
 def latest_activity(self):
     """Single latest translation activity by this person."""
     translations_person = ITranslationsPerson(self.context)
     latest = list(translations_person.translation_history[:1])
     if len(latest) == 0:
         return None
     else:
         return ActivityDescriptor(self.context, latest[0])
示例#13
0
    def access_level_description(self):
        """Must not be called when there's no translation group."""
        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.")
示例#14
0
 def test_checkSubmitConditions_rejects_license_decliners(self):
     # Users who have declined the relicensing agreement can't post
     # translations.
     decliner = self.factory.makePerson()
     ITranslationsPerson(decliner).translations_relicensing_agreement = (
         False)
     with person_logged_in(decliner):
         view = self._makeView()
         self.assertRaises(UnexpectedFormData, view._checkSubmitConditions)
示例#15
0
    def _canTranslate(self, person):
        """Is `person` in a position to translate?

        Someone who has declined the translations relicensing agreement
        is not.  Someone who hasn't decided on the agreement yet is, but
        may be redirected to a form to sign first.
        """
        translations_person = ITranslationsPerson(person)
        agreement = translations_person.translations_relicensing_agreement
        return agreement is not False
示例#16
0
 def __call__(self, context):
     """See `IContextSourceBinder`."""
     user = getUtility(ILaunchBag).user
     if user is not None and user.languages:
         translations_user = ITranslationsPerson(user)
         terms = [
             SimpleTerm(language, language.code, language.displayname)
             for language in translations_user.translatable_languages]
         if terms:
             return SimpleVocabulary(terms)
     return getVocabularyRegistry().get(None, "TranslatableLanguage")
示例#17
0
 def translation_teams(self):
     translation_teams = []
     for translation_team in self.context.translation_teams:
         # translation_team would be either a person or a team.
         translation_teams.append({
             'expert':
             translation_team,
             'groups':
             ITranslationsPerson(translation_team).translation_groups,
         })
     return translation_teams
示例#18
0
    def batchnav(self):
        """Iterate over person's translation_history."""
        translations_person = ITranslationsPerson(self.context)
        batchnav = BatchNavigator(translations_person.translation_history,
                                  self.request)

        pofiletranslatorset = getUtility(IPOFileTranslatorSet)
        batch = batchnav.currentBatch()
        self._pofiletranslator_cache = (
            pofiletranslatorset.prefetchPOFileTranslatorRelations(batch))

        return batchnav
示例#19
0
 def initial_values(self):
     """Set the default value for the relicensing radio buttons."""
     translations_person = ITranslationsPerson(self.context)
     # If the person has previously made a choice, we default to that.
     # Otherwise, we default to BSD, because that's what we'd prefer.
     if translations_person.translations_relicensing_agreement == False:
         default = TranslationRelicensingAgreementOptions.REMOVE
     else:
         default = TranslationRelicensingAgreementOptions.BSD
     return {
         "allow_relicensing": default,
         "back_to": self.request.get('back_to'),
     }
示例#20
0
    def submit_action(self, action, data):
        """Store person's decision about translations relicensing.

        The user's decision is stored through
        `ITranslationsPerson.translations_relicensing_agreement`
        which is backed by the TranslationRelicensingAgreement table.
        """
        translations_person = ITranslationsPerson(self.context)
        allow_relicensing = data['allow_relicensing']
        if allow_relicensing == TranslationRelicensingAgreementOptions.BSD:
            translations_person.translations_relicensing_agreement = True
            self.request.response.addInfoNotification(
                _("Thank you for BSD-licensing your translations."))
        elif (allow_relicensing ==
              TranslationRelicensingAgreementOptions.REMOVE):
            translations_person.translations_relicensing_agreement = False
            self.request.response.addInfoNotification(
                _("We respect your choice. "
                  "Thanks for trying out Launchpad Translations."))
        else:
            raise AssertionError("Unknown allow_relicensing value: %r" %
                                 allow_relicensing)
        self.next_url = self.getSafeRedirectURL(data['back_to'])
示例#21
0
    def submit_action(self, action, data):
        """Store person's decision about translations relicensing.

        The user's decision is stored through
        `ITranslationsPerson.translations_relicensing_agreement`
        which is backed by the TranslationRelicensingAgreement table.
        """
        translations_person = ITranslationsPerson(self.context)
        allow_relicensing = data['allow_relicensing']
        if allow_relicensing == TranslationRelicensingAgreementOptions.BSD:
            translations_person.translations_relicensing_agreement = True
            self.request.response.addInfoNotification(_(
                "Thank you for BSD-licensing your translations."))
        elif (allow_relicensing ==
            TranslationRelicensingAgreementOptions.REMOVE):
            translations_person.translations_relicensing_agreement = False
            self.request.response.addInfoNotification(_(
                "We respect your choice. "
                "Thanks for trying out Launchpad Translations."))
        else:
            raise AssertionError(
                "Unknown allow_relicensing value: %r" % allow_relicensing)
        self.next_url = self.getSafeRedirectURL(data['back_to'])
示例#22
0
    def test_query_count(self):
        person = self.factory.makePerson()
        login_person(person)
        ITranslationsPerson(person).translations_relicensing_agreement = True
        product = self.factory.makeProduct(owner=person)
        product.translationpermission = TranslationPermission.OPEN
        pofile = self.factory.makePOFile(
            potemplate=self.factory.makePOTemplate(
                productseries=product.series[0]))
        pofile.potemplate.productseries.product
        potmsgsets = [
            self.factory.makePOTMsgSet(pofile.potemplate) for i in range(10)]

        # Preload a few transaction-crossing caches that would give
        # extra queries to the first request.
        getUtility(ILaunchBag).time_zone
        getUtility(ILaunchpadCelebrities).ubuntu
        person.inTeam(getUtility(ILaunchpadCelebrities).admin)
        person.inTeam(getUtility(ILaunchpadCelebrities).rosetta_experts)

        def create_suggestions():
            for potmsgset in potmsgsets:
                pot = self.factory.makePOTemplate()
                self.factory.makeCurrentTranslationMessage(
                    potmsgset=self.factory.makePOTMsgSet(
                        singular=potmsgset.msgid_singular.msgid,
                        potemplate=pot),
                    language=pofile.language,
                    translations=[self.factory.getUniqueUnicode()])
                # A suggestion only shows up if it's actually in a
                # POFile.
                self.factory.makePOFile(
                    potemplate=pot, language=pofile.language)
                self.factory.makeSuggestion(
                    pofile=pofile, potmsgset=potmsgset)

            # Ensure that these are valid suggestions.
            templateset = getUtility(IPOTemplateSet)
            templateset.wipeSuggestivePOTemplatesCache()
            templateset.populateSuggestivePOTemplatesCache()

        nb_objects = 2
        recorder1, recorder2 = record_two_runs(
            lambda: create_initialized_view(
                pofile, '+translate', principal=person)(),
            create_suggestions, nb_objects)
        self.assertThat(recorder2, HasQueryCount.byEquality(recorder1))
示例#23
0
    def recent_activity(self):
        """Recent translation activity by this person.

        If the translation activity is associated with a project, we ensure
        that the project is active.
        """
        all_entries = ITranslationsPerson(self.context).translation_history

        def is_active(entry):
            potemplate = entry.pofile.potemplate
            if potemplate is None:
                return True
            product = potemplate.product
            product_is_active = (product is None or
                                 (product.active and product.translations_usage
                                  == ServiceUsage.LAUNCHPAD))
            return product_is_active

        active_entries = (entry for entry in all_entries if is_active(entry))
        return [
            ActivityDescriptor(self.context, entry)
            for entry in islice(active_entries, 10)
        ]
示例#24
0
def person_is_reviewer(person):
    """Is `person` a translations reviewer?"""
    groups = ITranslationsPerson(person).translation_groups
    return groups.any() is not None
 def test_hasTranslated(self):
     person = self.factory.makePerson()
     translationsperson = ITranslationsPerson(person)
     self.assertFalse(translationsperson.hasTranslated())
     self.factory.makeSuggestion(translator=person)
     self.assertTrue(translationsperson.hasTranslated())
示例#26
0
 def translators(self):
     """Return translators a person is a member of."""
     translations_person = ITranslationsPerson(self.context)
     return list(translations_person.translators)
 def test_baseline(self):
     person = ITranslationsPerson(self.factory.makePerson())
     self.assertTrue(verifyObject(ITranslationsPerson, person))
示例#28
0
 def _getReviewables(self, *args, **kwargs):
     """Shorthand for `self.person.getReviewableTranslationFiles`."""
     person = ITranslationsPerson(self.person)
     return list(person.getReviewableTranslationFiles(*args, **kwargs))
 def test_hasTranslated(self):
     person = self.factory.makePerson()
     translationsperson = ITranslationsPerson(person)
     self.assertFalse(translationsperson.hasTranslated())
     self.factory.makeSuggestion(translator=person)
     self.assertTrue(translationsperson.hasTranslated())
示例#30
0
def person_is_reviewer(person):
    """Is `person` a translations reviewer?"""
    groups = ITranslationsPerson(person).translation_groups
    return groups.any() is not None
 def _getReviewables(self, *args, **kwargs):
     """Shorthand for `self.person.getReviewableTranslationFiles`."""
     person = ITranslationsPerson(self.person)
     return list(person.getReviewableTranslationFiles(
         *args, **kwargs))