コード例 #1
0
ファイル: api.py プロジェクト: rvanlaar/easy-transifex
    def _update(self, request, project_slug, resource_slug, lang_code=None):
        # Permissions handling
        try:
            resource = Resource.objects.get(
                slug=resource_slug, project__slug=project_slug
            )
        except Resource.DoesNotExist:
            return rc.NOT_FOUND
        if lang_code == "source":
            language = resource.source_language
        else:
            try:
                language =  Language.objects.by_code_or_alias(lang_code)
            except Language.DoesNotExist:
                logger.error("Weird! Selected language code (%s) does "
                             "not match with any language in the database."
                             % lang_code)
                return BAD_REQUEST(
                    "Selected language code (%s) does not match with any"
                    "language in the database." % lang_code
                )

        team = Team.objects.get_or_none(resource.project, lang_code)
        check = ProjectPermission(request.user)
        if (not check.submit_translations(team or resource.project) or\
            not resource.accept_translations) and not\
                check.maintain(resource.project):
            return rc.FORBIDDEN

        try:
            t = Translation.get_object("create", request, resource, language)
            res = t.create()
        except BadRequestError, e:
            return BAD_REQUEST(unicode(e))
コード例 #2
0
ファイル: views.py プロジェクト: qikh/transifex
def cla_project_sign(request, project_slug):
    project = get_object_or_404(Project, slug=project_slug)
    cla = get_object_or_404(Cla, project=project)

    check = ProjectPermission(request.user)
    if not check.submit_translations(project, any_team=True):
        return permission_denied(request)

    try:
        signed_cla = request.user.cla_set.filter(project=project)[0]
    except IndexError:
        signed_cla = None

    if request.method == "POST" and not signed_cla:
        form = ClaForm(request.POST)
        if form.is_valid():
            kwargs = {"cla_sign": True, "project": project, "user": request.user}
            handle_pre_team(None, **kwargs)

            messages.success(request, _("You have signed the CLA."))

            return HttpResponseRedirect(reverse("cla_project_sign", args=[project_slug]))
    else:
        form = ClaForm()

    return render_to_response(
        "project_cla.html",
        {"project": project, "cla": cla, "signed_cla": signed_cla, "form": form},
        context_instance=RequestContext(request),
    )
コード例 #3
0
ファイル: models.py プロジェクト: 593in/transifex
 def can_unlock(self, user):
     """
     Perform permission check whether 'user' can unlock the Lock instance.
     """
     perm = ProjectPermission(user)
     return (self.owner == user) or perm.coordinate_team(
         project=self.rlstats.resource.project, language=self.rlstats.language)
コード例 #4
0
ファイル: views.py プロジェクト: garbelini/transifex
def lock_and_get_translation_file(request, project_slug, resource_slug, lang_code):
    """
    Lock and download the translations file.

    View to lock a resource for the requested language and as a second step to
    download (export+download) the translations in a formatted file.
    """

    resource = get_object_or_404(Resource, project__slug = project_slug,
        slug = resource_slug)

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) or not \
        resource.accept_translations:
        return permission_denied(request)

    language = get_object_or_404(Language, code=lang_code)
    lock = Lock.objects.get_valid(resource, language)
    can_lock = Lock.can_lock(resource, language, request.user)
    response = {}

    if not can_lock:
        #print_gray_text(You cannot assign this file to you)
        response['status'] = "FAILED"
        response['message'] = _("Sorry, you cannot lock this file!")
    else:
        # User can lock
        if not lock:
            try:
                # Lock the resource now
                Lock.objects.create_update(resource, language, request.user)
                response['status'] = 'OK'
                response['redirect'] = reverse('download_for_translation',
                    args=[resource.project.slug, resource.slug, lang_code])
            except:
                response['status'] = "FAILED"
                response['message'] = _("Failed to lock the resource!")
        else:
            if lock.owner == request.user:
                try:
                    # File already locked by me, so extend the lock period.
                    Lock.objects.create_update(resource, language, request.user)
                    response['status'] = 'OK'
                    response['redirect'] = reverse('download_for_translation',
                        args=[resource.project.slug, resource.slug, lang_code])
                except:
                    response['status'] = "FAILED"
                    response['message'] = _("Failed to extend lock period on "
                                            "the resource!")
            else:
                # File locked by someone else:
                response['status'] = "FAILED"
                response['message'] = _("You cannot lock it right now! (Locked "
                                        "by %s )" % (lock.owner,))

    return HttpResponse(simplejson.dumps(response), mimetype='application/json')
コード例 #5
0
ファイル: translation_object.py プロジェクト: 593in/transifex
    def _get_user_perms(self, user, project, resource, language,
            team, checksum, is_maintainer):
        """
        Get permissions for a user.

        Args:
            user: A User instance
            project: A Project instance
            resource: A Resource instance
            language: A Language instance
            team: A Team instance
            checksum: An md5 checksum representing a source entity
            is_maintiner: A boolean
        Returns:
            A dictionary containing various user permissions
        """
        check = ProjectPermission(user)
        can_review = check.proofread(project, language)
        can_submit_translations = check.submit_translations(
                team or resource.project)
        accept_translations = resource.accept_translations

        return {
            'can_review': can_review,
            'can_submit_translations': can_submit_translations,
            'accept_translations': accept_translations,
            'is_maintainer': check.maintain(project),
        }
コード例 #6
0
ファイル: views.py プロジェクト: rvanlaar/easy-transifex
def stringset_handling(request, project_slug, lang_code, resource_slug=None,
                     *args, **kwargs):
    """
    Function to serve AJAX data to the datatable holding the translating
    stringset.
    """

    project = get_object_or_404(Project, slug=project_slug)

    resources = []
    if resource_slug:
        try:
            resources = [ Resource.objects.get(slug=resource_slug,
                                    project__slug = project_slug) ]
        except Resource.DoesNotExist:
            raise Http404
    else:
        resources = Resource.objects.filter(project__slug = project_slug)

    try:
        language = Language.objects.by_code_or_alias(lang_code)
    except Language.DoesNotExist:
        raise Http404

    # Check if user is a team reviewer so that we can
    # send the extra info.
    check = ProjectPermission(request.user)
    review = check.proofread(project, language)

    # FIXME Do we need to check for non-POST requests and return an error?
    return _get_stringset(request.POST, resources, language, review=review)
コード例 #7
0
ファイル: api.py プロジェクト: isabella232/transifex-old-core
 def _has_perm(self, user, project):
     """
     Check that the user has access to this resource.
     """
     perm = ProjectPermission(user)
     if not perm.private(project):
         return False
     return True
コード例 #8
0
ファイル: __init__.py プロジェクト: tymofij/adofex
 def _has_perm(self, user, project):
     """
     Check that the user has access to this resource.
     """
     perm = ProjectPermission(user)
     if not perm.private(project):
         return False
     return True
コード例 #9
0
def _save_translation(source_string, translations, target_language, user):
    """Save a translation string to the database.

    This functions handle a signle source entity translation
    (could be pluralized).

    Currently, the function only returns warning strings.
    There is no message for success.

    Args:
        source_string: A Translation object of the string in the source
            language.
        translations: A (rule, string) tuple.
        target_language: The language the string is translated to.
        user: The translator.
    Returns:
        A list if strings to display to the user.
    Raises:
        An LotteBadRequestError exception in case of errors.
    """
    source_id = source_string.pk
    resource = source_string.resource
    source_language = resource.source_language
    warnings = []

    check = ProjectPermission(user)
    review_perm = check.proofread(resource.project, target_language)

    for rule, target_string in translations.items():
        rule = target_language.get_rule_num_from_name(rule)
        if rule != 5:
            # fetch correct source string for plural rule
            try:
                source_string = Translation.objects.get(
                    source_entity=source_string.source_entity,
                    language=source_language,
                    rule=rule)
            except Translation.DoesNotExist:
                # target language has extra plural forms
                pass

        # check for errors
        try:
            for ErrorValidator in create_error_validators(
                    resource.i18n_method):
                v = ErrorValidator(source_language, target_language, rule)
                v(source_string.string, target_string)
        except ValidationError, e:
            raise LotteBadRequestError(e.message)
        # check for warnings
        for WarningValidator in create_warning_validators(
                resource.i18n_method):
            v = WarningValidator(source_language, target_language, rule)
            try:
                v(source_string.string, target_string)
            except ValidationError, e:
                warnings.append(e.message)
コード例 #10
0
ファイル: views.py プロジェクト: garbelini/transifex
def _save_translation(source_string, translations, target_language, user):
    """Save a translation string to the database.

    This functions handle a signle source entity translation
    (could be pluralized).

    Currently, the function only returns warning strings.
    There is no message for success.

    Args:
        source_string: A Translation object of the string in the source
            language.
        translations: A (rule, string) tuple.
        target_language: The language the string is translated to.
        user: The translator.
    Returns:
        A list if strings to display to the user.
    Raises:
        An LotteBadRequestError exception in case of errors.
    """
    source_id = source_string.pk
    resource = source_string.resource
    source_language = resource.source_language
    warnings = []

    check = ProjectPermission(user)
    review_perm = check.proofread(resource.project, target_language)

    for rule, target_string in translations.items():
        rule = target_language.get_rule_num_from_name(rule)
        if rule != 5:
            # fetch correct source string for plural rule
            try:
                source_string = Translation.objects.get(
                    source_entity=source_string.source_entity,
                    language=source_language, rule=rule
                )
            except Translation.DoesNotExist:
                # target language has extra plural forms
                pass

        # check for errors
        try:
            for ErrorValidator in create_error_validators(resource.i18n_method):
                v = ErrorValidator(source_language, target_language, rule)
                v(source_string.string, target_string)
        except ValidationError, e:
            raise LotteBadRequestError(e.message)
        # check for warnings
        for WarningValidator in create_warning_validators(resource.i18n_method):
            v = WarningValidator(source_language, target_language, rule)
            try:
                v(source_string.string, target_string)
            except ValidationError, e:
                warnings.append(e.message)
コード例 #11
0
ファイル: views.py プロジェクト: garbelini/transifex
def exit(request, project_slug, lang_code, resource_slug=None, *args, **kwargs):
    """
    Exiting Lotte
    """
    if request.method != 'POST':
        return HttpResponse(status=405)

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not\
        check.maintain(project):
        return permission_denied(request)

    language = Language.objects.by_code_or_alias(lang_code)

    resources = []
    if resource_slug:
        resources = Resource.objects.filter(slug=resource_slug, project=project)
        if not resources:
            raise Http404
    else:
        resources = Resource.objects.filter(project=project)


    data = simplejson.loads(request.raw_post_data)

    if data.get('updated'):
        modified = True
        # ActionLog & Notification
        for resource in resources:
            nt = 'project_resource_translated'
            context = {'project': project,
                       'resource': resource,
                       'language': language,
                       'sender': request.user}
            object_list = [project, resource, language]
            if team:
                object_list.append(team)
            action_logging(request.user, object_list, nt, context=context)
    else:
        modified = False

    lotte_done.send(None, request=request, resources=resources,
        language=language, modified=modified)

    redirect_url = reverse('team_detail', args=[project_slug, language.code])

    if request.is_ajax():
        json = simplejson.dumps(dict(redirect=redirect_url))
        return HttpResponse(json, mimetype='application/json')

    return HttpResponseRedirect(redirect_url)
コード例 #12
0
ファイル: models.py プロジェクト: 593in/transifex
    def can_lock(resource, language, user):
        """
        Perform permission check whether 'user' can create a Lock.

        CAUTION: It does not perform lock counting check!
        """
        perm = ProjectPermission(user)
        if resource.accept_translations and (
            perm.submit_translations(resource.project, language) or
            perm.coordinate_team(project=resource.project, language=language)):
            return True
        return False
コード例 #13
0
 def render(self, context):
     obj = self.resolve(self.obj, context)
     perm = self.resolve(self.perm, context)
     if self.template_name:
         template_name = [
             self.resolve(obj, context)
             for obj in self.template_name.split(',')
         ]
     else:
         template_name = 'txpermissions/permission_form.html'
     request = context['request']
     extra_context = {}
     if self.approved:
         check = ProjectPermission(request.user)
         if request.user.is_authenticated():
             if (check.maintain(obj)
                     or request.user.has_perm('authority.add_permission')):
                 extra_context = {
                     'form_url':
                     txadd_url_for_obj(obj),
                     'next':
                     request.build_absolute_uri(),
                     'approved':
                     self.approved,
                     'form':
                     UserAjaxPermissionForm(perm,
                                            obj,
                                            approved=self.approved,
                                            initial=dict(codename=perm)),
                 }
     else:
         if request.user.is_authenticated(
         ) and not request.user.is_superuser:
             extra_context = {
                 'form_url':
                 txrequest_url_for_obj(obj),
                 'next':
                 request.build_absolute_uri(),
                 'approved':
                 self.approved,
                 'form':
                 UserAjaxPermissionForm(perm,
                                        obj,
                                        approved=self.approved,
                                        initial=dict(
                                            codename=perm,
                                            user=request.user.username)),
             }
     return template.loader.render_to_string(
         template_name,
         extra_context,
         context_instance=template.RequestContext(request))
コード例 #14
0
ファイル: views.py プロジェクト: 593in/transifex
def proofread(request, project_slug, lang_code, resource_slug=None, *args, **kwargs):
    """AJAX view that sets the reviewed flag on Translations to true or false.

    The request data is expected in JSON, with the following format:

    {
        'true': [1,2,3]
        'false': [4,5]
    }

    Note: The IDs are source entity IDs.
    """
    if request.method != 'POST':
        return HttpResponse(status=405)

    project = get_object_or_404(Project, slug=project_slug)
    resource = get_object_or_404(Resource, slug=resource_slug, project=project)

    try:
        language = Language.objects.by_code_or_alias(lang_code)
    except Language.DoesNotExist:
        raise Http404

    # Check if the user has the necessary permissions to review strings.
    check = ProjectPermission(request.user)
    if not check.proofread(project, language):
        return permission_denied(request)

    request_data = simplejson.loads(request.raw_post_data)

    if 'true' in request_data:
        source_entity_ids = request_data['true']
        translations = Translation.objects.filter(
            source_entity__id__in=source_entity_ids,
            language__code=lang_code,
        )
        translations.update(reviewed=True)
        ReviewHistory.add_many(translations, request.user, project.id, reviewed=True)

    if 'false' in request_data:
        source_entity_ids = request_data['false']
        translations = Translation.objects.filter(
            source_entity__id__in=source_entity_ids,
            language__code=lang_code,
        )
        translations.update(reviewed=False)
        ReviewHistory.add_many(translations, request.user, project.id, reviewed=False)

    invalidate_stats_cache(resource, language, user=request.user)

    return HttpResponse(status=200)
コード例 #15
0
ファイル: views.py プロジェクト: hfeeki/transifex
def exit(request, project_slug, lang_code, resource_slug=None, *args, **kwargs):
    """
    Exiting Lotte
    """

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not\
        check.maintain(project):
        return permission_denied(request)

    language = Language.objects.by_code_or_alias(lang_code)

    resources = []
    if resource_slug:
        resources = Resource.objects.filter(slug=resource_slug, project=project)
        if not resources:
            raise Http404
        url = reverse('resource_detail', args=[project_slug, resource_slug])
    else:
        resources = Resource.objects.filter(project=project)
        url = reverse('project_detail', args=[project_slug])

    if request.POST.get('updated', None) == 'true':
        modified = True
        # ActionLog & Notification
        for resource in resources:
            nt = 'project_resource_translated'
            context = {'project': project,
                       'resource': resource,
                       'language': language}
            object_list = [project, resource, language]
            action_logging(request.user, object_list, nt, context=context)
            if settings.ENABLE_NOTICES:
                txnotification.send_observation_notices_for(project,
                        signal=nt, extra_context=context)
    else:
        modified = False

    lotte_done.send(None, request=request, resources=resources,
        language=language, modified=modified)

    if request.is_ajax():
        json = simplejson.dumps(dict(redirect=url))
        return HttpResponse(json, mimetype='application/json')

    return HttpResponseRedirect(url)
コード例 #16
0
def txpermission_delete_form(context, obj, perm):
    """
    Render a html form to the delete view of the given permission. Return
    no content if the request-user has no permission to delete foreign
    permissions.
    """
    user = context['request'].user
    if user.is_authenticated():
        check = ProjectPermission(user)
        if (check.maintain(obj) or user.has_perm('authority.delete_permission')
                or user.pk == perm.creator.pk):
            return _base_permission_form(context, obj, perm,
                                         'project_delete_permission')
    return {'url': None}
コード例 #17
0
ファイル: translation_object.py プロジェクト: 593in/transifex
    def update(self, request, project_slug, resource_slug,
            language_code, api_version=2):
        """
        Update existing translations for multiple source entities
        of a resource at one go by permitted user(s).
        """
        try:
            project, resource, language = \
                    self._requested_objects(
                    project_slug, resource_slug, language_code)
            self._validate_language_is_not_source_language(
                    project.source_language, language)
            translations = request.data
            self._validate_translations_json_data(translations)
            team = Team.objects.get_or_none(project, language.code)

            check = ProjectPermission(request.user)
            # User must be a member of the project
            is_maintainer = check.maintain(project)
            # Allow only project members to issue this update request
            if not is_maintainer and  not (check.submit_translations(
                team or project) or check.proofread(project, language)):
                return FORBIDDEN_REQUEST(
                        "You are not allowed to update translations.")

            trans_obj_dict = self._translations_as_dict(
                    translations, resource, language)

            updated_translations = []
            se_ids = []
            for translation in translations:
                # All permission checks for a user is done here and
                # updated translations are collected in updated_tranlsations
                # and source_entity.id in se_ids
                self._process_translation_dict(translation, project, resource,
                        language, team, check, is_maintainer, request.user,
                        se_ids, updated_translations, trans_obj_dict)

            self._update_translations(updated_translations)

            keys = ['key', 'context', 'translation',
                    'reviewed', 'pluralized', 'wordcount',
                    'last_update', 'user', 'position', 'occurrences',]
            field_map, fields = self._get_update_fieldmap_and_fields(keys)

            return self._generate_translations_dict(
                    Translation.objects.filter( source_entity__id__in=se_ids,
                        language=language).values(*fields), field_map)
        except NotFoundError, e:
            return NOT_FOUND_REQUEST(unicode(e))
コード例 #18
0
def txpermission_request_approve_form(context, obj, perm):
    """
    Render a html form to the approve view of the given permission request.
    Return no content if the request-user has no permission to delete
    permissions.
    """
    user = context['request'].user
    if user.is_authenticated():
        check = ProjectPermission(user)
        if (check.maintain(obj)
                or user.has_perm('authority.approve_permission_requests')):
            return _base_permission_form(context, obj, perm,
                                         'project_approve_permission_request')
    return {'url': None}
コード例 #19
0
ファイル: translation_object.py プロジェクト: 593in/transifex
    def update(self, request, project_slug, resource_slug,
            language_code, source_hash, api_version=2):
        """
        Update existing translations for a source entity of a resource.
        """
        try:
            project, resource, language = \
                    self._requested_objects(project_slug,
                    resource_slug, language_code)
            # A translation in source language cannot be updated
            self._validate_language_is_not_source_language(
                    project.source_language, language)
            try:
                source_entity = SourceEntity.objects.get(
                        string_hash=source_hash, resource=resource)
            except SourceEntity.DoesNotExist, e:
                return rc.NOT_FOUND
            team = Team.objects.get_or_none(project, language.code)
            data = request.data
            # This is a hack to use the methods from TranslationObjectsHandler
            data['source_entity_hash'] = source_hash
            check = ProjectPermission(request.user)
            is_maintainer = check.maintain(project)
            # Allow only project members to issue this update request
            if not is_maintainer and  not (check.submit_translations(
                team or project) or check.proofread(project, language)):
                return FORBIDDEN_REQUEST(
                        "You are not allowed to update translations.")
            trans_obj_dict = self._translations_as_dict(
                    [data], resource, language)
            if not trans_obj_dict:
                return rc.NOT_FOUND
            updated_translations = []
            se_ids = []
            # All permission checks for a user is done here and
            # updated translations are collected in updated_tranlsations
            # and source_entity.id in se_ids
            self._process_translation_dict(data, project, resource,
                    language, team, check, is_maintainer, request.user,
                    se_ids, updated_translations, trans_obj_dict)
            # Updated translations are saved to db
            self._update_translations(updated_translations)

            translations = Translation.objects.filter(
                    source_entity=source_entity, language=language)
            field_map = self._get_fieldmap()
            fields = self._get_fields_for_translation_value_query_set(field_map)
            return self._generate_translations_dict(
                    Translation.objects.filter( source_entity__id__in=se_ids,
                        language=language).values(*fields), field_map, True)
コード例 #20
0
def clone_language(request,
                   project_slug=None,
                   resource_slug=None,
                   source_lang_code=None,
                   target_lang_code=None):
    '''
    Get a resource, a src lang and a target lang and clone all translation
    strings for the src to the target.

    The user is redirected to the online editor for the target language.
    '''

    resource = get_object_or_404(Resource,
                                 slug=resource_slug,
                                 project__slug=project_slug)

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, target_lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) or not \
        resource.accept_translations:
        return permission_denied(request)

    source_lang = get_object_or_404(Language, code=source_lang_code)
    target_lang = get_object_or_404(Language, code=target_lang_code)

    # get the strings which will be cloned
    strings = Translation.objects.filter(resource=resource,
                                         language=source_lang)

    # If the language we want to create, has the same plural rules with the
    # source, we also copy the pluralized translations!
    if not source_lang.get_pluralrules() == target_lang.get_pluralrules():
        strings = strings.exclude(source_entity__pluralized=True)

    # clone them in new translation
    for s in strings:
        Translation.objects.get_or_create(language=target_lang,
                                          string=s.string,
                                          source_entity=s.source_entity,
                                          rule=s.rule,
                                          resource=s.resource)

    invalidate_stats_cache(resource, target_lang, user=request.user)
    return HttpResponseRedirect(
        reverse('translate_resource',
                args=[project_slug, resource_slug, target_lang_code]), )
コード例 #21
0
ファイル: views.py プロジェクト: rvanlaar/easy-transifex
def tab_suggestions_snippet(request, entity_id, lang_code):
    """Return a template snippet with entity & translation details."""

    source_entity = get_object_or_404(SourceEntity, pk=entity_id)

    check = ProjectPermission(request.user)
    if not check.private(source_entity.resource.project):
        return permission_denied(request)

    current_translation = source_entity.get_translation(lang_code)

    return render_to_response("tab_suggestions_snippet.html", {
        'source_entity': source_entity,
        'lang_code': lang_code,
        'current_translation': current_translation
        },
    context_instance = RequestContext(request))
コード例 #22
0
def tab_suggestions_snippet(request, entity_id, lang_code):
    """Return a template snippet with entity & translation details."""

    source_entity = get_object_or_404(SourceEntity, pk=entity_id)

    check = ProjectPermission(request.user)
    if not check.private(source_entity.resource.project):
        return permission_denied(request)

    current_translation = source_entity.get_translation(lang_code)

    return render_to_response("tab_suggestions_snippet.html", {
        'source_entity': source_entity,
        'lang_code': lang_code,
        'current_translation': current_translation
    },
                              context_instance=RequestContext(request))
コード例 #23
0
ファイル: views.py プロジェクト: garbelini/transifex
def clone_language(request, project_slug=None, resource_slug=None,
            source_lang_code=None, target_lang_code=None):
    '''
    Get a resource, a src lang and a target lang and clone all translation
    strings for the src to the target.

    The user is redirected to the online editor for the target language.
    '''

    resource = get_object_or_404(Resource, slug=resource_slug,
                                 project__slug=project_slug)

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, target_lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) or not \
        resource.accept_translations:
        return permission_denied(request)

    source_lang = get_object_or_404(Language, code=source_lang_code)
    target_lang = get_object_or_404(Language, code=target_lang_code)

    # get the strings which will be cloned
    strings = Translation.objects.filter(
                resource = resource,
                language = source_lang)

    # If the language we want to create, has the same plural rules with the
    # source, we also copy the pluralized translations!
    if not source_lang.get_pluralrules() == target_lang.get_pluralrules():
        strings = strings.exclude(source_entity__pluralized = True)

    # clone them in new translation
    for s in strings:
        Translation.objects.get_or_create(
            language=target_lang, string=s.string,
            source_entity=s.source_entity, rule=s.rule,
            resource=s.resource
        )

    invalidate_stats_cache(resource, target_lang, user=request.user)
    return HttpResponseRedirect(reverse('translate_resource', args=[project_slug,
                                resource_slug, target_lang_code]),)
コード例 #24
0
def txpermission_request_delete_form(context, obj, perm):
    """
    Render a html form to the delete view of the given permission request.
    Return no content if the request-user has no permission to delete
    permissions.
    """
    user = context['request'].user
    if user.is_authenticated():
        check = ProjectPermission(user)
        form_kwargs = _base_permission_form(
            context, obj, perm, 'project_delete_permission_request')
        if check.maintain(obj) or user.has_perm('authority.delete_permission'):
            form_kwargs['is_requestor'] = False
            return form_kwargs
        if not perm.approved and perm.user == user:
            form_kwargs['is_requestor'] = True
            return form_kwargs
    return {'url': None}
コード例 #25
0
def add_edit_developer_comment_extra(request, project_slug, *args, **kwargs):
    """
    View for handling AJAX calls from Lotte in order to add/edit the
    developer comment for a source entity.

    Only maintainers can edit it.
    """

    # Permissions handling
    project = get_object_or_404(Project, slug=project_slug)
    check = ProjectPermission(request.user)
    if not check.maintain(project):
        content = {'error': True, 'message': _('Permission error.')}
    elif not request.POST:
        content = {'error': True, 'message': _('Bad request.')}
    else:
        previous_comment = None
        try:
            se = SourceEntity.objects.get(id=request.POST.get(
                'source_entity_id', None),
                                          resource__project=project)
            previous_comment_extra = se.developer_comment_extra
            se.developer_comment_extra = request.POST.get('comment_extra', '')
            se.save()
            content = {
                'error': False,
                'comment': se.developer_comment,
                'comment_extra': se.developer_comment_extra,
            }
        except SourceEntity.DoesNotExist:
            content = {
                'error': True,
                'message': _('No such Source Entity for the given project.'),
            }
        except Exception, e:
            logger.error('Lotte: Error while editing developer comment: %s' %
                         (e.message or str(e)))
            content = {
                'error':
                True,
                'message':
                _('Ops! Something weird happened. The admins '
                  'were notified about it.'),
            }
コード例 #26
0
ファイル: views.py プロジェクト: garbelini/transifex
def update_translation(request, project_slug, resource_slug, lang_code=None):
    """Ajax view that gets an uploaded translation as a file and saves it.

    If the language is not specified, the translation does not exist yet.
    Othewise, this is an update.

    Returns:
        Either an error message, or nothing for success.
    """
    resource = get_object_or_404(
        Resource.objects.select_related('project'),
        project__slug=project_slug, slug=resource_slug
    )
    if lang_code is None:
        lang_code = request.POST.get('language_code', None)
    target_language = get_object_or_404(Language, code=lang_code)
    project = resource.project
    # Get the team if exists to use it for permissions and links
    team = Team.objects.get_or_none(project, lang_code)

    check = ProjectPermission(request.user)
    if (not check.submit_translations(team or resource.project) or\
            not resource.accept_translations) and not\
            check.maintain(resource.project):
        return HttpResponse(
            simplejson.dumps({
                    'msg': _("You are not allowed to upload a translation."),
                    'status': 403,
            }),
            status=403, content_type='text/plain'
        )

    content = content_from_uploaded_file(request.FILES)
    try:
        _save_translation(resource, target_language, request.user, content)
    except FormatsBackendError, e:
        return HttpResponse(
            simplejson.dumps({
                    'msg': unicode(e),
                    'status': 400,
            }),
            status=400, content_type='text/plain'
        )
コード例 #27
0
ファイル: views.py プロジェクト: rvanlaar/easy-transifex
def tab_details_snippet(request, entity_id, lang_code):
    """Return a template snippet with entity & translation details."""

    source_entity = get_object_or_404(SourceEntity, pk=entity_id)

    check = ProjectPermission(request.user)
    if not check.private(source_entity.resource.project):
        return permission_denied(request)

    language = get_object_or_404(Language, code=lang_code)
    translation = source_entity.get_translation(language.code)

    return list_detail.object_detail(request,
        queryset=SourceEntity.objects.all(),
        object_id=entity_id,
        template_name="tab_details_snippet.html",
        template_object_name='source_entity',
        extra_context={"translation": translation,
            "project": source_entity.resource.project})
コード例 #28
0
def update_translation(request, project_slug, resource_slug, lang_code=None):
    """Ajax view that gets an uploaded translation as a file and saves it.

    If the language is not specified, the translation does not exist yet.
    Othewise, this is an update.

    Returns:
        Either an error message, or nothing for success.
    """
    resource = get_object_or_404(Resource.objects.select_related('project'),
                                 project__slug=project_slug,
                                 slug=resource_slug)
    if lang_code is None:
        lang_code = request.POST.get('language_code', None)
    target_language = get_object_or_404(Language, code=lang_code)
    project = resource.project
    # Get the team if exists to use it for permissions and links
    team = Team.objects.get_or_none(project, lang_code)

    check = ProjectPermission(request.user)
    if (not check.submit_translations(team or resource.project) or\
            not resource.accept_translations) and not\
            check.maintain(resource.project):
        return HttpResponse(simplejson.dumps({
            'msg':
            _("You are not allowed to upload a translation."),
            'status':
            403,
        }),
                            status=403,
                            content_type='text/plain')

    content = content_from_uploaded_file(request.FILES)
    try:
        _save_translation(resource, target_language, request.user, content)
    except FormatsBackendError, e:
        return HttpResponse(simplejson.dumps({
            'msg': unicode(e),
            'status': 400,
        }),
                            status=400,
                            content_type='text/plain')
コード例 #29
0
ファイル: permission.py プロジェクト: 593in/transifex
def project_delete_permission_request(request, project_slug, permission_pk):
    """
    View for deleting a request of permission of a user.

    This view is an abstraction of a txpermissions.views method.
    """
    project, permission=_get_project_and_permission(project_slug, permission_pk)

    # It's necessary to distinguish between maintainer and normal users that
    # did the request
    if request.user.id==permission.user.id:
        notice_type = 'project_submit_access_request_withdrawn'
        sendto = project.maintainers.all()
    else:
        notice_type = 'project_submit_access_request_denied'
        sendto = [permission.user]

    notice = {
            'type': notice_type,
            'object': project,
            'sendto': sendto,
            'extra_context': {'project': project,
                              'user_request': permission.user,
                              'user_action': request.user,
            },
        }

    check = ProjectPermission(request.user)
    if check.maintain(project) or \
        request.user.has_perm('authority.delete_permission') or \
        request.user.pk == permission.creator.pk:
        return delete_permission_or_request(request, permission, False,
                                            extra_context={ 'notice': notice },)


    check = ProjectPermission(request.user)
    if check.maintain(project) or \
            request.user.has_perm('authority.delete_permission') or \
            request.user.pk == permission.creator.pk:
        return delete_permission_or_request(request, permission, False)

    return permission_denied(request)
コード例 #30
0
ファイル: views.py プロジェクト: rvanlaar/easy-transifex
def add_edit_developer_comment_extra(request, project_slug, *args, **kwargs):
    """
    View for handling AJAX calls from Lotte in order to add/edit the
    developer comment for a source entity.

    Only maintainers can edit it.
    """

    # Permissions handling
    project = get_object_or_404(Project, slug=project_slug)
    check = ProjectPermission(request.user)
    if not check.maintain(project):
        content = {'error': True, 'message': _('Permission error.')}
    elif not request.POST:
        content = {'error': True, 'message': _('Bad request.')}
    else:
        previous_comment = None
        try:
            se = SourceEntity.objects.get(
                id=request.POST.get('source_entity_id', None),
                resource__project=project)
            previous_comment_extra = se.developer_comment_extra
            se.developer_comment_extra = request.POST.get('comment_extra', '')
            se.save()
            content = {
                'error': False,
                'comment': se.developer_comment,
                'comment_extra': se.developer_comment_extra,
                }
        except SourceEntity.DoesNotExist:
            content = {
                'error': True,
                'message': _('No such Source Entity for the given project.'),
                }
        except Exception, e:
            logger.error('Lotte: Error while editing developer comment: %s' %
                (e.message or str(e)))
            content = {
                'error': True,
                'message': _('Ops! Something weird happened. The admins '
                    'were notified about it.'),
                }
コード例 #31
0
def suggestion_vote(request, entity_id, lang_code, suggestion_id, direction):
    """Vote up or down for a suggestion."""

    suggestion = get_object_or_404(Suggestion, pk=suggestion_id)

    # Permissions handling
    check = ProjectPermission(request.user)
    if not check.private(suggestion.source_entity.resource.project):
        return permission_denied(request)

    #FIXME: All basic POST checks could be done in a decorator.
    if not request.method == "POST":
        return HttpResponseBadRequest(_("POST method only allowed."))

    if direction == 'up':
        suggestion.vote_up(request.user)
    elif direction == 'down':
        suggestion.vote_down(request.user)

    return HttpResponse(status=200)
コード例 #32
0
ファイル: api.py プロジェクト: hfeeki/transifex
 def _read(self, request, project_slug):
     """
     Return a list of projects or the details for a specific project.
     """
     if project_slug is None:
         # Use pagination
         p = Project.objects.for_user(request.user)
         res, msg = paginate(p, request.GET.get("start"), request.GET.get("end"))
         if res is None:
             return BAD_REQUEST(msg)
         return res
     else:
         try:
             p = Project.objects.get(slug=project_slug)
             perm = ProjectPermission(request.user)
             if not perm.private(p):
                 return rc.FORBIDDEN
         except Project.DoesNotExist:
             return rc.NOT_FOUND
         return p
コード例 #33
0
def stringset_handling(request,
                       project_slug,
                       lang_code,
                       resource_slug=None,
                       *args,
                       **kwargs):
    """
    Function to serve AJAX data to the datatable holding the translating
    stringset.
    """

    project = get_object_or_404(Project, slug=project_slug)

    resources = []
    if resource_slug:
        try:
            resources = [
                Resource.objects.get(slug=resource_slug,
                                     project__slug=project_slug)
            ]
        except Resource.DoesNotExist:
            raise Http404
    else:
        resources = Resource.objects.filter(project__slug=project_slug)

    try:
        language = Language.objects.by_code_or_alias(lang_code)
    except Language.DoesNotExist:
        raise Http404

    # Check if user is a team reviewer so that we can
    # send the extra info.
    check = ProjectPermission(request.user)
    review = check.proofread(project, language)

    # FIXME Do we need to check for non-POST requests and return an error?
    return _get_stringset(request.POST,
                          resources,
                          language,
                          review=review,
                          session=request.session)
コード例 #34
0
 def _read(self, request, project_slug):
     """
     Return a list of projects or the details for a specific project.
     """
     if project_slug is None:
         # Use pagination
         p = Project.objects.for_user(request.user)
         res, msg = paginate(p, request.GET.get('start'),
                             request.GET.get('end'))
         if res is None:
             return BAD_REQUEST(msg)
         return res
     else:
         try:
             p = Project.objects.get(slug=project_slug)
             perm = ProjectPermission(request.user)
             if not perm.private(p):
                 return rc.FORBIDDEN
         except Project.DoesNotExist:
             return rc.NOT_FOUND
         return p
コード例 #35
0
ファイル: views.py プロジェクト: 593in/transifex
def suggestion_vote(request, entity_id, lang_code, suggestion_id, direction):
    
    """Vote up or down for a suggestion."""

    suggestion = get_object_or_404(Suggestion, pk=suggestion_id)

    # Permissions handling
    check = ProjectPermission(request.user)
    if not check.private(suggestion.source_entity.resource.project):
        return permission_denied(request)

    #FIXME: All basic POST checks could be done in a decorator.
    if not request.method == "POST":
        return HttpResponseBadRequest(_("POST method only allowed."))

    if direction == 'up':
        suggestion.vote_up(request.user)
    elif direction == 'down':
        suggestion.vote_down(request.user)

    return HttpResponse(status=200)
コード例 #36
0
ファイル: views.py プロジェクト: 593in/transifex
def suggestion_create(request, entity_id, lang_code):
    """Create a suggestion for an entity and a language."""

    source_entity = get_object_or_404(SourceEntity, pk=entity_id)

    # Permissions handling
    check = ProjectPermission(request.user)
    if not check.private(source_entity.resource.project):
        return permission_denied(request)

    #FIXME: All basic POST checks could be done in a decorator.
    if not request.method == "POST":
        return HttpResponseBadRequest(_("POST method only allowed."))
    suggestion_string = request.POST['suggestion_string']
    if not suggestion_string:
        return HttpResponseBadRequest(_("POST variable 'suggestion_string' missing."))

    language = Language.objects.by_code_or_alias(lang_code)
    source_entity.suggestions.create(language=language,
                                     string=request.POST['suggestion_string'],
                                     user=request.user)
    return HttpResponse(status=200)
コード例 #37
0
def tab_details_snippet(request, entity_id, lang_code):
    """Return a template snippet with entity & translation details."""

    source_entity = get_object_or_404(SourceEntity, pk=entity_id)

    check = ProjectPermission(request.user)
    if not check.private(source_entity.resource.project):
        return permission_denied(request)

    language = get_object_or_404(Language, code=lang_code)
    translation = source_entity.get_translation(language.code)

    return list_detail.object_detail(request,
                                     queryset=SourceEntity.objects.all(),
                                     object_id=entity_id,
                                     template_name="tab_details_snippet.html",
                                     template_object_name='source_entity',
                                     extra_context={
                                         "translation": translation,
                                         "project":
                                         source_entity.resource.project
                                     })
コード例 #38
0
def suggestion_create(request, entity_id, lang_code):
    """Create a suggestion for an entity and a language."""

    source_entity = get_object_or_404(SourceEntity, pk=entity_id)

    # Permissions handling
    check = ProjectPermission(request.user)
    if not check.private(source_entity.resource.project):
        return permission_denied(request)

    #FIXME: All basic POST checks could be done in a decorator.
    if not request.method == "POST":
        return HttpResponseBadRequest(_("POST method only allowed."))
    suggestion_string = request.POST['suggestion_string']
    if not suggestion_string:
        return HttpResponseBadRequest(
            _("POST variable 'suggestion_string' missing."))

    language = Language.objects.by_code_or_alias(lang_code)
    source_entity.suggestions.create(language=language,
                                     string=request.POST['suggestion_string'],
                                     user=request.user)
    return HttpResponse(status=200)
コード例 #39
0
def cla_project_sign(request, project_slug):
    project = get_object_or_404(Project, slug=project_slug)
    cla = get_object_or_404(Cla, project=project)

    check = ProjectPermission(request.user)
    if not check.submit_translations(project, any_team=True):
        return permission_denied(request)

    try:
        signed_cla = request.user.cla_set.filter(project=project)[0]
    except IndexError:
        signed_cla = None

    if request.method == 'POST' and not signed_cla:
        form = ClaForm(request.POST)
        if form.is_valid():
            kwargs = {
                'cla_sign': True,
                'project': project,
                'user': request.user
            }
            handle_pre_team(None, **kwargs)

            messages.success(request, _("You have signed the CLA."))

            return HttpResponseRedirect(
                reverse('cla_project_sign', args=[project_slug]), )
    else:
        form = ClaForm()

    return render_to_response("project_cla.html", {
        'project': project,
        'cla': cla,
        'signed_cla': signed_cla,
        'form': form
    },
                              context_instance=RequestContext(request))
コード例 #40
0
    def _update(self, request, project_slug, resource_slug, lang_code=None):
        # Permissions handling
        try:
            resource = Resource.objects.select_related('project').get(
                slug=resource_slug, project__slug=project_slug)
        except Resource.DoesNotExist:
            return rc.NOT_FOUND
        source_push = False
        if lang_code == "source":
            language = resource.source_language
            source_push = True
        else:
            try:
                language = Language.objects.by_code_or_alias(lang_code)
            except Language.DoesNotExist:
                logger.error("Weird! Selected language code (%s) does "
                             "not match with any language in the database." %
                             lang_code)
                return BAD_REQUEST(
                    "Selected language code (%s) does not match with any"
                    "language in the database." % lang_code)

        team = Team.objects.get_or_none(resource.project, lang_code)
        check = ProjectPermission(request.user)
        if source_push and not check.maintain(resource.project):
            return rc.FORBIDDEN
        elif (not check.submit_translations(team or resource.project) or\
            not resource.accept_translations) and not\
                check.maintain(resource.project):
            return rc.FORBIDDEN

        try:
            t = Translation.get_object("create", request, resource, language)
            res = t.create()
        except BadRequestError, e:
            return BAD_REQUEST(unicode(e))
コード例 #41
0
def project_delete_permission_request(request, project_slug, permission_pk):
    """
    View for deleting a request of permission of a user.

    This view is an abstraction of a txpermissions.views method.
    """
    project, permission = _get_project_and_permission(project_slug,
                                                      permission_pk)

    # It's necessary to distinguish between maintainer and normal users that
    # did the request
    if request.user.id == permission.user.id:
        notice_type = 'project_submit_access_request_withdrawn'
        sendto = project.maintainers.all()
    else:
        notice_type = 'project_submit_access_request_denied'
        sendto = [permission.user]

    notice = {
        'type': notice_type,
        'object': project,
        'sendto': sendto,
        'extra_context': {
            'project': project,
            'user_request': permission.user,
            'user_action': request.user,
        },
    }

    check = ProjectPermission(request.user)
    if check.maintain(project) or \
        request.user.has_perm('authority.delete_permission') or \
        request.user.pk == permission.creator.pk:
        return delete_permission_or_request(
            request,
            permission,
            False,
            extra_context={'notice': notice},
        )

    check = ProjectPermission(request.user)
    if check.maintain(project) or \
            request.user.has_perm('authority.delete_permission') or \
            request.user.pk == permission.creator.pk:
        return delete_permission_or_request(request, permission, False)

    return permission_denied(request)
コード例 #42
0
def exit(request,
         project_slug,
         lang_code,
         resource_slug=None,
         *args,
         **kwargs):
    """
    Exiting Lotte
    """
    if request.method != 'POST':
        return HttpResponse(status=405)

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not\
        check.maintain(project):
        return permission_denied(request)

    language = Language.objects.by_code_or_alias(lang_code)

    resources = []
    if resource_slug:
        resources = Resource.objects.filter(slug=resource_slug,
                                            project=project)
        if not resources:
            raise Http404
    else:
        resources = Resource.objects.filter(project=project)

    data = simplejson.loads(request.raw_post_data)

    if data.get('updated'):
        modified = True
        # ActionLog & Notification
        for resource in resources:
            nt = 'project_resource_translated'
            context = {
                'project': project,
                'resource': resource,
                'language': language,
                'sender': request.user
            }
            object_list = [project, resource, language]
            if team:
                object_list.append(team)
            action_logging(request.user, object_list, nt, context=context)
    else:
        modified = False

    lotte_done.send(None,
                    request=request,
                    resources=resources,
                    language=language,
                    modified=modified)

    redirect_url = reverse('team_detail', args=[project_slug, language.code])

    if request.is_ajax():
        json = simplejson.dumps(dict(redirect=redirect_url))
        return HttpResponse(json, mimetype='application/json')

    return HttpResponseRedirect(redirect_url)
コード例 #43
0
def project_access_control_edit(request, project_slug):
    project = get_object_or_404(Project, slug=project_slug)
    outsourced = project.outsource
    if request.method == 'POST':
        form = ProjectAccessControlForm(request.POST,
                                        instance=project,
                                        user=request.user)
        if form.is_valid():
            access_control = form.cleaned_data['access_control']
            project_type = form.cleaned_data['project_type']
            project = form.save(commit=False)
            project_hub = project.outsource
            hub_request = None

            # TODO call signal project_outsourced_changed
            if 'outsourced' != project_type:
                project.outsource = None
            else:
                check = ProjectPermission(request.user)
                if not (check.maintain(project)
                        and check.maintain(project_hub)):
                    # If the user is not maintainer of both projects it does
                    # not associate the outsource project directly.
                    # It does a request instead.
                    try:
                        hub_request = HubRequest.objects.get(project=project)
                    except ObjectDoesNotExist:
                        hub_request = HubRequest(project=project)
                    hub_request.project_hub = project_hub
                    hub_request.user = request.user
                    hub_request.save()

                    messages.success(
                        request,
                        _("Requested to join the '%s' project hub.") %
                        project_hub)
                    # ActionLog & Notification
                    # TODO: Use signals
                    nt = 'project_hub_join_requested'
                    context = {
                        'hub_request': hub_request,
                        'sender': request.user
                    }

                    # Logging action
                    action_logging(request.user, [project, project_hub],
                                   nt,
                                   context=context)

                    if settings.ENABLE_NOTICES:
                        # Send notification for project hub maintainers
                        notification.send(project_hub.maintainers.all(), nt,
                                          context)

                    return HttpResponseRedirect(
                        reverse('project_detail', args=[project.slug]), )

            if 'hub' == project_type:
                project.is_hub = True
            else:
                project.is_hub = False

            if ('free_for_all' == access_control
                    and project_type != "outsourced"):
                project.anyone_submit = True
            else:
                project.anyone_submit = False

            # Check if cla form exists before sending the signal
            if 'limited_access' == access_control and \
            form.cleaned_data.has_key('cla_license_text'):
                # send signal to save CLA
                signals.cla_create.send(
                    sender='project_access_control_edit_view',
                    project=project,
                    license_text=form.cleaned_data['cla_license_text'],
                    request=request)

            project.save()
            form.save_m2m()
            handle_stats_on_access_control_edit(project)
            project_outsourced_changed.send(sender=project_hub)

            if outsourced and not project.outsource:
                # Drop resources from all-resources release of the hub project
                update_all_release(outsourced)

                # Logging action
                nt = 'project_hub_left'
                context = {
                    'project': project,
                    'project_hub': outsourced,
                    'sender': request.user
                }
                action_logging(request.user, [project, outsourced],
                               nt,
                               context=context)

            return HttpResponseRedirect(
                reverse('project_detail', args=[project.slug]), )

    else:
        form = ProjectAccessControlForm(instance=project, user=request.user)

    return render_to_response('projects/project_form_access_control.html', {
        'project_permission': True,
        'project': project,
        'form': form,
    },
                              context_instance=RequestContext(request))
コード例 #44
0
ファイル: views.py プロジェクト: rvanlaar/easy-transifex
def push_translation(request, project_slug, lang_code, *args, **kwargs):
    """
    Client pushes an id and a translation string.

    Id is considered to be of the source translation string and the string is
    in the target_lang.

    FIXME: Document in detail the form of the 'strings' POST variable.
    """

    logger.debug("POST data when saving translation: %s" % request.POST)
    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not\
        check.maintain(project):
        return permission_denied(request)

    if not request.POST:
        return HttpResponseBadRequest()

    data = simplejson.loads(request.raw_post_data)
    strings = data["strings"]

    try:
        target_language = Language.objects.by_code_or_alias(lang_code)
    except Language.DoesNotExist:
        raise Http404

    # This dictionary will hold the results of the save operation and will map
    # status code for each translation pushed, to indicate the result on each
    # translation push separately.
    push_response_dict = {}

    # Form the strings dictionary, get as Json object
    # The fields are the following:
    # id-> source_entity id
    # translations-> translation strings (includes all plurals)
    # context-> source_entity context
    # occurrence-> occurrence (not yet well supported)
    # Iterate through all the row data that have been sent.
    for row in strings:
        source_id = int(row['id'])
        try:
            source_string = Translation.objects.select_related(depth=1).get(
                id=source_id
            )
        except Translation.DoesNotExist:
            # TODO: Log or inform here
            push_response_dict[source_id] = { 'status':400,
                 'message':_("Source string cannot be identified in the DB")}
            # If the source_string cannot be identified in the DB then go to next
            # translation pair.
            continue

        if not source_string.resource.accept_translations:
            push_response_dict[source_id] = { 'status':400,
                 'message':_("The resource of this source string is not "
                    "accepting translations.") }

        # If the translated source string is pluralized check that all the
        # source language supported rules have been filled in, else return error
        # and donot save the translations.
        if source_string.source_entity.pluralized:
            error_flag = False
            for rule in target_language.get_pluralrules():
                if rule in row['translations'] and row['translations'][rule] != "":
                    continue
                else:
                    error_flag = True
            if error_flag:
                error_flag = False
                # Check also if all of them are "". If yes, delete all the plurals!
                for rule in target_language.get_pluralrules():
                    if rule in row['translations'] and row['translations'][rule] == "":
                        continue
                    else:
                        error_flag = True
            if error_flag:
                push_response_dict[source_id] = { 'status':400,
                    'message':(_("Cannot save unless plural translations are either "
                               "completely specified or entirely empty!"))}
                # Skip the save as we hit on an error.
                continue
        try:
            msgs = _save_translation(
                source_string, row['translations'],
                target_language, request.user
            )
            if not msgs:
                push_response_dict[source_id] = {'status': 200}
            else:
                push_response_dict[source_id] = {
                    'status': 200, 'message': msgs[-1]
                }
        except LotteBadRequestError, e:
            push_response_dict[source_id] = {
                'status': 400, 'message': e.message
            }
        except Exception, e:
            logger.error(
                "Unexpected exception raised: %s" % e.message, exc_info=True
            )
            push_response_dict[source_id] = {
                'status': 400, 'message': e.message
            }
コード例 #45
0
ファイル: views.py プロジェクト: rvanlaar/easy-transifex
def translate(request, project_slug, lang_code, resource_slug=None,
                     *args, **kwargs):
    """
    Main lotte view.
    """

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not\
        check.maintain(project):
        return permission_denied(request)

    resources = []
    if resource_slug:
        resource_list = [get_object_or_404(Resource, slug=resource_slug,
            project=project)]
    else:
        resource_list = Resource.objects.filter(project=project)

        # Return a page explaining that the project has multiple source langs and
        # cannot be translated as a whole.
        if resource_list.values('source_language').distinct().count() > 1:
            messages.info(request,_(
                          "There are multiple source languages for this project. "
                          "You will only be able to translate resources for one "
                          "source language at a time."))
            return HttpResponseRedirect(reverse('project_detail',
                                        args=[project_slug]),)

    # Filter resources that are not accepting translations
    for resource in resource_list:
        if resource.accept_translations:
            resources.append(resource)

    # If no resource accepting translations, raise a 403
    if not resources:
        return permission_denied(request)

    target_language = Language.objects.by_code_or_alias_or_404(lang_code)

    # If it is an attempt to edit the source language, redirect the user to
    # resource_detail and show him a message explaining the reason.
    if target_language == get_source_language(resources):
        messages.error(request,_(
                       "Cannot edit the source language because this would "
                       "result in translation mismatches! If you want to "
                       "update the source strings consider using the transifex "
                       "command-line client."))
        if resource_slug:
            return HttpResponseRedirect(reverse('resource_detail',
                                                args=[project_slug,
                                                      resource_slug]),)
        else:
            return HttpResponseRedirect(reverse('project_detail',
                                                args=[project_slug]),)

    total_strings = SourceEntity.objects.filter(
        resource__in = resources).count()

    translated_strings = Translation.objects.filter(
        resource__in = resources,
        language = target_language,
        source_entity__pluralized=False,
        rule = 5).count()

    # Include counting of pluralized entities
    for pluralized_entity in SourceEntity.objects.filter(resource__in = resources,
                                                         pluralized=True):
        plurals_translated = Translation.objects.filter(
            language=target_language,
            source_entity=pluralized_entity).count()
        if plurals_translated == len(target_language.get_pluralrules()):
            translated_strings += 1

    if len(resources) > 1:
        translation_resource = None
    else:
        translation_resource = resources[0]

    contributors = User.objects.filter(pk__in=Translation.objects.filter(
        resource__in = resources,
        language = target_language,
        rule = 5).values_list("user", flat=True))

    lotte_init.send(None, request=request, resources=resources,
        language=target_language)

    if target_language in [team.language for team in project.available_teams]:
        team_language = True
    else:
        team_language = False

    GtModel = get_model('gtranslate', 'Gtranslate')
    try:
        auto_translate = GtModel.objects.get(project=project)
    except GtModel.DoesNotExist:
        auto_translate = None

    return render_to_response("translate.html",
        { 'project' : project,
          'resource' : translation_resource,
          'target_language' : target_language,
          'translated_strings': translated_strings,
          'untranslated_strings': total_strings - translated_strings,
          'contributors': contributors,
          'resources': resources,
          'resource_slug': resource_slug,
          'languages': Language.objects.all(),
          'auto_translate': auto_translate,
          'spellcheck_supported_langs' : SPELLCHECK_SUPPORTED_LANGS,
          'team_language': team_language
        },
        context_instance = RequestContext(request))
コード例 #46
0
def lock_and_get_translation_file(request, project_slug, resource_slug,
                                  lang_code):
    """
    Lock and download the translations file.

    View to lock a resource for the requested language and as a second step to
    download (export+download) the translations in a formatted file.
    """

    resource = get_object_or_404(Resource,
                                 project__slug=project_slug,
                                 slug=resource_slug)

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) or not \
        resource.accept_translations:
        return permission_denied(request)

    language = get_object_or_404(Language, code=lang_code)
    lock = Lock.objects.get_valid(resource, language)
    can_lock = Lock.can_lock(resource, language, request.user)
    response = {}

    if not can_lock:
        #print_gray_text(You cannot assign this file to you)
        response['status'] = "FAILED"
        response['message'] = _("Sorry, you cannot lock this file!")
    else:
        # User can lock
        if not lock:
            try:
                # Lock the resource now
                Lock.objects.create_update(resource, language, request.user)
                response['status'] = 'OK'
                response['redirect'] = reverse(
                    'download_for_translation',
                    args=[resource.project.slug, resource.slug, lang_code])
            except:
                response['status'] = "FAILED"
                response['message'] = _("Failed to lock the resource!")
        else:
            if lock.owner == request.user:
                try:
                    # File already locked by me, so extend the lock period.
                    Lock.objects.create_update(resource, language,
                                               request.user)
                    response['status'] = 'OK'
                    response['redirect'] = reverse(
                        'download_for_translation',
                        args=[resource.project.slug, resource.slug, lang_code])
                except:
                    response['status'] = "FAILED"
                    response['message'] = _("Failed to extend lock period on "
                                            "the resource!")
            else:
                # File locked by someone else:
                response['status'] = "FAILED"
                response['message'] = _(
                    "You cannot lock it right now! (Locked "
                    "by %s )" % (lock.owner, ))

    return HttpResponse(simplejson.dumps(response),
                        mimetype='application/json')
コード例 #47
0
ファイル: api.py プロジェクト: hfeeki/transifex
    def update(self, request, project_slug, resource_slug, language_code=None, api_version=1):
        """
        Update resource translations of a project by the UUID of a StorageFile.
        """
        try:
            project = Project.objects.get(slug=project_slug)
            resource = Resource.objects.get(slug=resource_slug, project=project)
        except (Project.DoesNotExist, Resource.DoesNotExist):
            return rc.NOT_FOUND

        # Permissions handling
        team = Team.objects.get_or_none(project, language_code)
        check = ProjectPermission(request.user)
        if (not check.submit_translations(team or project) or not resource.accept_translations) and not check.maintain(
            project
        ):
            return rc.FORBIDDEN

        if "application/json" in request.content_type:
            if "uuid" in request.data:
                uuid = request.data["uuid"]
                storagefile = StorageFile.objects.get(uuid=uuid)
                language = storagefile.language

                logger.debug(
                    "Going to insert strings from %s (%s) to %s/%s"
                    % (storagefile.name, storagefile.uuid, project_slug, resource.slug)
                )

                strings_added, strings_updated = 0, 0
                parser = storagefile.find_parser()
                language = storagefile.language
                fhandler = parser(filename=storagefile.get_storage_path())
                fhandler.set_language(language)
                fhandler.bind_resource(resource)
                fhandler.contents_check(fhandler.filename)

                try:
                    fhandler.parse_file()
                    strings_added, strings_updated = fhandler.save2db(user=request.user)
                except Exception, e:
                    logger.error(e.message, exc_info=True)
                    return BAD_REQUEST("Error importing file: %s" % e)
                else:
                    messages = []
                    if strings_added > 0:
                        messages.append(_("%i strings added") % strings_added)
                    if strings_updated > 0:
                        messages.append(_("%i strings updated") % strings_updated)
                retval = {
                    "strings_added": strings_added,
                    "strings_updated": strings_updated,
                    "redirect": reverse("resource_detail", args=[project_slug, resource.slug]),
                }

                logger.debug("Extraction successful, returning: %s" % retval)

                # Set StorageFile to 'bound' status, which means that it is
                # bound to some translation resource
                storagefile.bound = True
                storagefile.save()

                # If any string added/updated
                if retval["strings_added"] > 0 or retval["strings_updated"] > 0:
                    modified = True
                else:
                    modified = False

                post_submit_translation.send(
                    None, request=request, resource=resource, language=language, modified=modified
                )

                return HttpResponse(simplejson.dumps(retval), mimetype="application/json")
            else:
                return BAD_REQUEST("Missing request data.")
コード例 #48
0
def proofread(request,
              project_slug,
              lang_code,
              resource_slug=None,
              *args,
              **kwargs):
    """AJAX view that sets the reviewed flag on Translations to true or false.

    The request data is expected in JSON, with the following format:

    {
        'true': [1,2,3]
        'false': [4,5]
    }

    Note: The IDs are source entity IDs.
    """
    if request.method != 'POST':
        return HttpResponse(status=405)

    project = get_object_or_404(Project, slug=project_slug)
    resource = get_object_or_404(Resource, slug=resource_slug, project=project)

    try:
        language = Language.objects.by_code_or_alias(lang_code)
    except Language.DoesNotExist:
        raise Http404

    # Check if the user has the necessary permissions to review strings.
    check = ProjectPermission(request.user)
    if not check.proofread(project, language):
        return permission_denied(request)

    request_data = simplejson.loads(request.raw_post_data)

    if 'true' in request_data:
        source_entity_ids = request_data['true']
        translations = Translation.objects.filter(
            source_entity__id__in=source_entity_ids,
            language__code=lang_code,
        )
        translations.update(reviewed=True)
        ReviewHistory.add_many(translations,
                               request.user,
                               project.id,
                               reviewed=True)

    if 'false' in request_data:
        source_entity_ids = request_data['false']
        translations = Translation.objects.filter(
            source_entity__id__in=source_entity_ids,
            language__code=lang_code,
        )
        translations.update(reviewed=False)
        ReviewHistory.add_many(translations,
                               request.user,
                               project.id,
                               reviewed=False)

    invalidate_stats_cache(resource, language, user=request.user)

    return HttpResponse(status=200)
コード例 #49
0
def translate(request,
              project_slug,
              lang_code,
              resource_slug=None,
              *args,
              **kwargs):
    """
    Main lotte view.
    """

    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not\
        check.maintain(project):
        return permission_denied(request)

    resources = []
    if resource_slug:
        resource_list = [
            get_object_or_404(Resource, slug=resource_slug, project=project)
        ]
    else:
        resource_list = Resource.objects.filter(project=project)

        # Return a page explaining that the project has multiple source langs and
        # cannot be translated as a whole.
        if resource_list.values('source_language').distinct().count() > 1:
            messages.info(
                request,
                _("There are multiple source languages for this project. "
                  "You will only be able to translate resources for one "
                  "source language at a time."))
            return HttpResponseRedirect(
                reverse('project_detail', args=[project_slug]), )

    # Filter resources that are not accepting translations
    for resource in resource_list:
        if resource.accept_translations:
            resources.append(resource)

    # If no resource accepting translations, raise a 403
    if not resources:
        return permission_denied(request)

    target_language = Language.objects.by_code_or_alias_or_404(lang_code)

    # If it is an attempt to edit the source language, redirect the user to
    # resource_detail and show him a message explaining the reason.
    if target_language == get_source_language(resources):
        messages.error(
            request,
            _("Cannot edit the source language because this would "
              "result in translation mismatches! If you want to "
              "update the source strings consider using the transifex "
              "command-line client."))
        if resource_slug:
            return HttpResponseRedirect(
                reverse('resource_detail', args=[project_slug,
                                                 resource_slug]), )
        else:
            return HttpResponseRedirect(
                reverse('project_detail', args=[project_slug]), )

    total_strings = SourceEntity.objects.filter(resource__in=resources).count()

    translated_strings = Translation.objects.filter(
        resource__in=resources,
        language=target_language,
        source_entity__pluralized=False,
        rule=5).count()

    reviewed_strings = Translation.objects.filter(
        resource__in=resources,
        language=target_language,
        source_entity__pluralized=False,
        rule=5,
        reviewed=True).count()

    # Include counting of pluralized entities
    for pluralized_entity in SourceEntity.objects.filter(
            resource__in=resources, pluralized=True):
        plurals_translated = Translation.objects.filter(
            language=target_language, source_entity=pluralized_entity).count()
        if plurals_translated == len(target_language.get_pluralrules()):
            translated_strings += 1

    if len(resources) > 1:
        translation_resource = None
    else:
        translation_resource = resources[0]

    contributors = User.objects.filter(pk__in=Translation.objects.filter(
        resource__in=resources, language=target_language, rule=5).values_list(
            "user", flat=True))

    lotte_init.send(None,
                    request=request,
                    resources=resources,
                    language=target_language)

    if target_language in [team.language for team in project.available_teams]:
        team_language = True
    else:
        team_language = False

    GtModel = get_model('gtranslate', 'Gtranslate')
    try:
        auto_translate = GtModel.objects.get(project=project)
    except GtModel.DoesNotExist:
        auto_translate = None
    """
    if cache.get('lotte_%s' % request.session.session_key, None):
        cache.delete('lotte_%s' % request.session.session_key)
    """

    #Set rtl to True if target_language is an RTL language
    rtl = False
    if target_language.code in settings.RTL_LANGUAGE_CODES:
        rtl = True

    return render_to_response("translate.html", {
        'project': project,
        'resource': translation_resource,
        'target_language': target_language,
        'translated_strings': translated_strings,
        'reviewed_strings': reviewed_strings,
        'untranslated_strings': total_strings - translated_strings,
        'contributors': contributors,
        'resources': resources,
        'resource_slug': resource_slug,
        'languages': Language.objects.all(),
        'auto_translate': auto_translate,
        'spellcheck_supported_langs': SPELLCHECK_SUPPORTED_LANGS,
        'team_language': team_language,
        'RTL': rtl,
    },
                              context_instance=RequestContext(request))
コード例 #50
0
def push_translation(request, project_slug, lang_code, *args, **kwargs):
    """
    Client pushes an id and a translation string.

    Id is considered to be of the source translation string and the string is
    in the target_lang.

    FIXME: Document in detail the form of the 'strings' POST variable.
    """

    logger.debug("POST data when saving translation: %s" % request.POST)
    # Permissions handling
    # Project should always be available
    project = get_object_or_404(Project, slug=project_slug)
    team = Team.objects.get_or_none(project, lang_code)
    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not\
        check.maintain(project):
        return permission_denied(request)

    if not request.POST:
        return HttpResponseBadRequest()

    data = simplejson.loads(request.raw_post_data)
    strings = data["strings"]

    try:
        target_language = Language.objects.by_code_or_alias(lang_code)
    except Language.DoesNotExist:
        raise Http404

    # This dictionary will hold the results of the save operation and will map
    # status code for each translation pushed, to indicate the result on each
    # translation push separately.
    push_response_dict = {}

    # Form the strings dictionary, get as Json object
    # The fields are the following:
    # id-> source_entity id
    # translations-> translation strings (includes all plurals)
    # context-> source_entity context
    # occurrence-> occurrence (not yet well supported)
    # Iterate through all the row data that have been sent.
    for row in strings:
        source_id = int(row['id'])
        try:
            source_string = Translation.objects.select_related(depth=1).get(
                id=source_id)
        except Translation.DoesNotExist:
            # TODO: Log or inform here
            push_response_dict[source_id] = {
                'status': 400,
                'message': _("Source string cannot be identified in the DB")
            }
            # If the source_string cannot be identified in the DB then go to next
            # translation pair.
            continue

        if not source_string.resource.accept_translations:
            push_response_dict[source_id] = {
                'status':
                400,
                'message':
                _("The resource of this source string is not "
                  "accepting translations.")
            }

        # If the translated source string is pluralized check that all the
        # source language supported rules have been filled in, else return error
        # and donot save the translations.
        if source_string.source_entity.pluralized:
            error_flag = False
            for rule in target_language.get_pluralrules():
                if rule in row[
                        'translations'] and row['translations'][rule] != "":
                    continue
                else:
                    error_flag = True
            if error_flag:
                error_flag = False
                # Check also if all of them are "". If yes, delete all the plurals!
                for rule in target_language.get_pluralrules():
                    if rule in row['translations'] and row['translations'][
                            rule] == "":
                        continue
                    else:
                        error_flag = True
            if error_flag:
                push_response_dict[source_id] = {
                    'status':
                    400,
                    'message':
                    (_("Cannot save unless plural translations are either "
                       "completely specified or entirely empty!"))
                }
                # Skip the save as we hit on an error.
                continue
        try:
            msgs = _save_translation(source_string, row['translations'],
                                     target_language, request.user)
            if not msgs:
                push_response_dict[source_id] = {'status': 200}
            else:
                push_response_dict[source_id] = {
                    'status': 200,
                    'message': msgs[-1]
                }
        except LotteBadRequestError, e:
            push_response_dict[source_id] = {
                'status': 400,
                'message': e.message
            }
        except Exception, e:
            logger.error("Unexpected exception raised: %s" % e.message,
                         exc_info=True)
            push_response_dict[source_id] = {
                'status': 400,
                'message': e.message
            }
コード例 #51
0
def resource_translation_toggle_watch(request, project_slug, resource_slug, language_code):
    """Add/Remove a TranslationWatch for a specific user."""

    if request.method != 'POST':
        return json_error(_('Must use POST to activate'))

    if not settings.ENABLE_NOTICES:
        return json_error(_('Notification is not enabled'))

    resource = get_object_or_404(Resource, slug=resource_slug,
                                project__slug=project_slug)
    project = resource.project
    language = get_object_or_404(Language, code=language_code)
    team = Team.objects.get_or_none(project, language_code)

    check = ProjectPermission(request.user)
    if not check.submit_translations(team or project) and not \
        check.maintain(project) and not \
        request.user.has_perm('watches.add_translationwatch') and not \
        request.user.has_perm('watches.delete_translationwatch'):
        return permission_denied(request)

    url = reverse('resource_translation_toggle_watch', args=(project_slug,
        resource_slug, language_code))

    try:
        twatch = TranslationWatch.objects.get(resource=resource,
            language=language)

        result = {
            'style': 'watch_add',
            'title': _('Watch it'),
            'id': twatch.id,
            'url': url,
            'error': None,
        }

        notification.stop_observing(twatch, request.user,
            signal='project_resource_translation_changed')

    except (TranslationWatch.DoesNotExist,
        notification.ObservedItem.DoesNotExist):

        try:
            twatch = TranslationWatch.objects.get_or_create(resource=resource,
                language=language)[0]

            result = {
                'style': 'watch_remove',
                'title': _('Stop watching'),
                'id': twatch.id,
                'url': url,
                'error': None,
            }

            notification.observe(twatch, request.user,
                'project_resource_translation_changed',
                signal='project_resource_translation_changed')

        except WatchException, e:
            return json_error(e.message, result)