コード例 #1
0
ファイル: views.py プロジェクト: saily/weblate
def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if not check_rate_limit(request):
            messages.error(
                request,
                _('Too many messages sent, please try again later!')
            )
        elif form.is_valid():
            mail_admins_contact(
                request,
                '%(subject)s',
                CONTACT_TEMPLATE,
                form.cleaned_data,
                form.cleaned_data['email'],
            )
            return redirect('home')
    else:
        initial = get_initial_contact(request)
        if request.GET.get('t') in CONTACT_SUBJECTS:
            initial['subject'] = CONTACT_SUBJECTS[request.GET['t']]
        form = ContactForm(initial=initial)

    return render(
        request,
        'accounts/contact.html',
        {
            'form': form,
            'title': _('Contact'),
        }
    )
コード例 #2
0
ファイル: acl.py プロジェクト: daleathan/weblate
def change_access(request, project):
    obj = get_project(request, project)

    if not request.user.has_perm('billing:project.permissions', obj):
        raise PermissionDenied()

    form = ProjectAccessForm(request.POST, instance=obj)

    if not form.is_valid():
        for error in form.errors:
            for message in form.errors[error]:
                messages.error(request, message)
    else:
        form.save()
        Change.objects.create(
            project=obj,
            action=Change.ACTION_ACCESS_EDIT,
            user=request.user,
            details={'access_control': obj.access_control},
        )
        messages.success(
            request, _('Project access control has been changed.')
        )

    return redirect(
        'manage-access',
        project=obj.slug,
    )
コード例 #3
0
ファイル: views.py プロジェクト: dekoza/weblate
    def post(self, request, **kwargs):
        component = self.get_component()
        if not request.user.has_perm('screenshot.add', component):
            raise PermissionDenied()
        self._add_form = ScreenshotForm(request.POST, request.FILES)
        if self._add_form.is_valid():
            obj = Screenshot.objects.create(
                component=component,
                user=request.user,
                **self._add_form.cleaned_data
            )
            request.user.profile.uploaded += 1
            request.user.profile.save(update_fields=['uploaded'])

            try_add_source(request, obj)
            messages.success(
                request,
                _(
                    'Screenshot has been uploaded, '
                    'you can now assign it to source strings.'
                )
            )
            return redirect(obj)
        messages.error(
            request,
            _('Failed to upload screenshot, please fix errors below.')
        )
        return self.get(request, **kwargs)
コード例 #4
0
ファイル: edit.py プロジェクト: saily/weblate
def auto_translation(request, project, subproject, lang):
    translation = get_translation(request, project, subproject, lang)
    project = translation.subproject.project
    if not can_automatic_translation(request.user, project):
        raise PermissionDenied()

    autoform = AutoForm(translation, request.user, request.POST)

    if translation.subproject.locked or not autoform.is_valid():
        messages.error(request, _('Failed to process form!'))
        return redirect(translation)

    updated = auto_translate(
        request.user,
        translation,
        autoform.cleaned_data['subproject'],
        autoform.cleaned_data['inconsistent'],
        autoform.cleaned_data['overwrite']
    )

    import_message(
        request, updated,
        _('Automatic translation completed, no strings were updated.'),
        ungettext(
            'Automatic translation completed, %d string was updated.',
            'Automatic translation completed, %d strings were updated.',
            updated
        )
    )

    return redirect(translation)
コード例 #5
0
ファイル: edit.py プロジェクト: saily/weblate
def save_zen(request, project, subproject, lang):
    """Save handler for zen mode."""
    translation = get_translation(request, project, subproject, lang)
    user_locked = translation.is_user_locked(request.user)

    form = TranslationForm(
        request.user.profile, translation, None, request.POST
    )
    if not can_translate(request.user, translation):
        messages.error(
            request,
            _('You don\'t have privileges to save translations!')
        )
    elif not form.is_valid():
        messages.error(request, _('Failed to save translation!'))
    elif not user_locked:
        unit = form.cleaned_data['unit']

        perform_translation(unit, form, request)

    return render(
        request,
        'zen-response.html',
        {},
    )
コード例 #6
0
ファイル: settings.py プロジェクト: daleathan/weblate
def change_component(request, project, component):
    obj = get_component(request, project, component)

    if not request.user.has_perm('component.edit', obj):
        raise Http404()

    if request.method == 'POST':
        form = ComponentSettingsForm(request.POST, instance=obj)
        if form.is_valid():
            form.save()
            messages.success(request, _('Settings saved'))
            return redirect(
                'settings', project=obj.project.slug, component=obj.slug
            )
        else:
            messages.error(
                request,
                _('Invalid settings, please check the form for errors!')
            )
    else:
        form = ComponentSettingsForm(instance=obj)

    return render(
        request,
        'component-settings.html',
        {
            'project': obj.project,
            'object': obj,
            'form': form,
        }
    )
コード例 #7
0
ファイル: views.py プロジェクト: dekoza/weblate
def reset_password_set(request):
    """Perform actual password reset."""
    user = User.objects.get(pk=request.session['perform_reset'])
    if user.has_usable_password():
        request.session.flush()
        request.session.set_expiry(None)
        messages.error(
            request,
            _('Password reset has been already completed!')
        )
        return redirect('login')
    if request.method == 'POST':
        form = SetPasswordForm(user, request.POST)
        if form.is_valid():
            request.session.set_expiry(None)
            form.save(request, delete_session=True)
            return redirect('login')
    else:
        form = SetPasswordForm(user)
    return render(
        request,
        'accounts/reset.html',
        {
            'title': _('Password reset'),
            'form': form,
            'captcha_form': None,
            'second_stage': True,
        }
    )
コード例 #8
0
ファイル: edit.py プロジェクト: nijel/weblate
def handle_merge(translation, request, next_unit_url):
    """Handle unit merging."""
    mergeform = MergeForm(translation, request.GET)
    if not mergeform.is_valid():
        messages.error(request, _('Invalid merge request!'))
        return None

    unit = mergeform.cleaned_data['unit']
    merged = mergeform.cleaned_data['merge_unit']

    if not request.user.has_perm('unit.edit', unit):
        messages.error(
            request,
            _('Insufficient privileges for saving translations.')
        )
        return None

    # Store unit
    saved = unit.translate(request, merged.target, merged.state)
    # Update stats if there was change
    if saved:
        request.user.profile.translated += 1
        request.user.profile.save()
    # Redirect to next entry
    return HttpResponseRedirect(next_unit_url)
コード例 #9
0
ファイル: acl.py プロジェクト: daleathan/weblate
def add_user(request, project):
    """Add user to a project."""
    obj, form = check_user_form(request, project, True)

    if form is not None:
        try:
            user = form.cleaned_data['user']
            obj.add_user(user)
            Change.objects.create(
                project=obj,
                action=Change.ACTION_ADD_USER,
                user=request.user,
                details={'username': user.username},
            )
            messages.success(
                request, _('User has been added to this project.')
            )
        except Group.DoesNotExist:
            messages.error(
                request, _('Failed to find group to add a user!')
            )

    return redirect(
        'manage-access',
        project=obj.slug,
    )
コード例 #10
0
ファイル: views.py プロジェクト: saily/weblate
 def post(self, request, **kwargs):
     component = self.get_component(kwargs)
     if not can_add_screenshot(request.user, component.project):
         raise PermissionDenied()
     self._add_form = ScreenshotForm(request.POST, request.FILES)
     if self._add_form.is_valid():
         obj = Screenshot.objects.create(
             component=component,
             **self._add_form.cleaned_data
         )
         try_add_source(request, obj)
         messages.success(
             request,
             _(
                 'Screenshot has been uploaded, '
                 'you can now assign it to source strings.'
             )
         )
         return redirect(obj)
     else:
         messages.error(
             request,
             _('Failed to upload screenshot, please fix errors below.')
         )
         return self.get(request, **kwargs)
コード例 #11
0
ファイル: edit.py プロジェクト: nijel/weblate
def handle_translate(request, translation, this_unit_url, next_unit_url):
    """Save translation or suggestion to database and backend."""
    # Antispam protection
    antispam = AntispamForm(request.POST)
    if not antispam.is_valid():
        # Silently redirect to next entry
        return HttpResponseRedirect(next_unit_url)

    form = TranslationForm(
        request.user, translation, None, request.POST
    )
    if not form.is_valid():
        show_form_errors(request, form)
        return None

    unit = form.cleaned_data['unit']
    go_next = True

    if 'suggest' in request.POST:
        go_next = perform_suggestion(unit, form, request)
    elif not request.user.has_perm('unit.edit', unit):
        messages.error(
            request,
            _('Insufficient privileges for saving translations.')
        )
    else:
        go_next = perform_translation(unit, form, request)

    # Redirect to next entry
    if go_next:
        return HttpResponseRedirect(next_unit_url)
    return HttpResponseRedirect(this_unit_url)
コード例 #12
0
ファイル: edit.py プロジェクト: nijel/weblate
def comment(request, pk):
    """Add new comment."""
    unit = get_object_or_404(Unit, pk=pk)
    request.user.check_access(unit.translation.component.project)

    if not request.user.has_perm('comment.add', unit.translation):
        raise PermissionDenied()

    form = CommentForm(request.POST)

    if form.is_valid():
        if form.cleaned_data['scope'] == 'global':
            lang = None
        else:
            lang = unit.translation.language
        Comment.objects.add(
            unit,
            request.user,
            lang,
            form.cleaned_data['comment']
        )
        messages.success(request, _('Posted new comment'))
    else:
        messages.error(request, _('Failed to add comment!'))

    return redirect_next(request.POST.get('next'), unit)
コード例 #13
0
ファイル: acl.py プロジェクト: daleathan/weblate
def delete_user(request, project):
    """Remove user from a project."""
    obj, form = check_user_form(request, project, True)

    if form is not None:
        owners = User.objects.all_admins(obj)
        user = form.cleaned_data['user']
        is_owner = owners.filter(pk=user.pk).exists()
        if is_owner and owners.count() <= 1:
            messages.error(request, _('You can not remove last owner!'))
        else:
            obj.remove_user(user)
            Change.objects.create(
                project=obj,
                action=Change.ACTION_REMOVE_USER,
                user=request.user,
                details={'username': user.username},
            )
            messages.success(
                request, _('User has been removed from this project.')
            )

    return redirect(
        'manage-access',
        project=obj.slug,
    )
コード例 #14
0
ファイル: views.py プロジェクト: dekoza/weblate
def mail_admins_contact(request, subject, message, context, sender, to):
    """Send a message to the admins, as defined by the ADMINS setting."""
    LOGGER.info(
        'contact form from %s',
        sender,
    )
    if not to and settings.ADMINS:
        to = [a[1] for a in settings.ADMINS]
    elif not settings.ADMINS:
        messages.error(
            request,
            _('Message could not be sent to administrator!')
        )
        LOGGER.error(
            'ADMINS not configured, can not send message!'
        )
        return

    mail = EmailMultiAlternatives(
        '{0}{1}'.format(settings.EMAIL_SUBJECT_PREFIX, subject % context),
        message % context,
        to=to,
        headers={'Reply-To': sender},
    )

    mail.send(fail_silently=False)

    messages.success(
        request,
        _('Message has been sent to administrator.')
    )
コード例 #15
0
ファイル: ratelimit.py プロジェクト: dekoza/weblate
        def rate_wrap(request, *args, **kwargs):
            if request.method == 'POST':
                session = request.session
                now = time()
                k_timeout = '{}_timeout'.format(scope)
                k_attempts = '{}_attempts'.format(scope)
                # Reset expired counter
                if (k_timeout in session and
                        k_attempts in session and
                        session[k_timeout] <= now):
                    session[k_attempts] = 0

                # Get current attempts
                attempts = session.get(k_attempts, 0)

                # Did we hit the limit?
                if attempts >= get_rate_setting(scope, 'ATTEMPTS'):
                    # Rotate session token
                    rotate_token(request)
                    # Logout user
                    if request.user.is_authenticated:
                        logout(request)
                    messages.error(
                        request,
                        _('Too many attempts, you have been logged out!')
                    )
                    return redirect('login')

                session[k_attempts] = attempts + 1
                if k_timeout not in session:
                    window = get_rate_setting(scope, 'WINDOW')
                    session[k_timeout] = now + window

            return function(request, *args, **kwargs)
コード例 #16
0
ファイル: edit.py プロジェクト: nijel/weblate
def perform_translation(unit, form, request):
    """Handle translation and stores it to a backend."""
    # Remember old checks
    oldchecks = set(
        unit.active_checks().values_list('check', flat=True)
    )

    # Run AutoFixes on user input
    if not unit.translation.is_template:
        new_target, fixups = fix_target(form.cleaned_data['target'], unit)
    else:
        new_target = form.cleaned_data['target']
        fixups = []

    # Save
    saved = unit.translate(
        request,
        new_target,
        form.cleaned_data['state']
    )

    # Should we skip to next entry
    if not saved:
        revert_rate_limit('translate', request)
        return True

    # Warn about applied fixups
    if fixups:
        messages.info(
            request,
            _('Following fixups were applied to translation: %s') %
            ', '.join([force_text(f) for f in fixups])
        )

    # Get new set of checks
    newchecks = set(
        unit.active_checks().values_list('check', flat=True)
    )

    # Did we introduce any new failures?
    if saved and newchecks > oldchecks:
        # Show message to user
        messages.error(
            request,
            _(
                'The translation has been saved, however there '
                'are some newly failing checks: {0}'
            ).format(
                ', '.join(
                    [force_text(CHECKS[check].name) for check in newchecks]
                )
            )
        )
        # Stay on same entry
        return False

    return True
コード例 #17
0
ファイル: basic.py プロジェクト: nijel/weblate
def new_language(request, project, component):
    obj = get_component(request, project, component)

    form_class = get_new_language_form(request, obj)
    can_add = obj.can_add_new_language(request)

    if request.method == 'POST':
        form = form_class(obj, request.POST)

        if form.is_valid():
            langs = form.cleaned_data['lang']
            kwargs = {
                'user': request.user,
                'author': request.user,
                'component': obj,
                'details': {},
            }
            for language in Language.objects.filter(code__in=langs):
                kwargs['details']['language'] = language.code
                if can_add:
                    obj.add_new_language(language, request)
                    Change.objects.create(
                        action=Change.ACTION_ADDED_LANGUAGE,
                        **kwargs
                    )
                elif obj.new_lang == 'contact':
                    Change.objects.create(
                        action=Change.ACTION_REQUESTED_LANGUAGE,
                        **kwargs
                    )
                    messages.success(
                        request,
                        _(
                            "A request for a new translation has been "
                            "sent to the project's maintainers."
                        )
                    )
            return redirect(obj)
        messages.error(
            request,
            _('Please fix errors in the form.')
        )
    else:
        form = form_class(obj)

    return render(
        request,
        'new-language.html',
        {
            'object': obj,
            'project': obj.project,
            'form': form,
            'can_add': can_add,
        }
    )
コード例 #18
0
ファイル: views.py プロジェクト: saily/weblate
 def rate_wrap(request, *args, **kwargs):
     attempts = request.session.get('auth_attempts', 0)
     if (request.method == 'POST' and
             attempts >= settings.AUTH_MAX_ATTEMPTS):
         logout(request)
         messages.error(
             request,
             _('Too many authentication attempts!')
         )
         return redirect('login')
     return function(request, *args, **kwargs)
コード例 #19
0
ファイル: changes.py プロジェクト: daleathan/weblate
 def _get_queryset_language(self):
     """Filtering by language"""
     if self.translation is None and 'lang' in self.request.GET:
         try:
             self.language = Language.objects.get(
                 code=self.request.GET['lang']
             )
         except Language.DoesNotExist:
             messages.error(
                 self.request,
                 _('Failed to find matching language!')
             )
コード例 #20
0
ファイル: changes.py プロジェクト: daleathan/weblate
 def _get_queryset_user(self):
     """Filtering by user"""
     if 'user' in self.request.GET:
         try:
             self.user = User.objects.get(
                 username=self.request.GET['user']
             )
         except User.DoesNotExist:
             messages.error(
                 self.request,
                 _('Failed to find matching user!')
             )
コード例 #21
0
ファイル: views.py プロジェクト: dekoza/weblate
def handle_dismiss(request):
    try:
        error = ConfigurationError.objects.get(
            pk=int(request.POST['pk'])
        )
        if 'ignore' in request.POST:
            error.ignored = True
            error.save(update_fields=['ignored'])
        else:
            error.delete()
    except (ValueError, KeyError, ConfigurationError.DoesNotExist):
        messages.error(request, _('Failed to dismiss configuration error!'))
    return redirect('admin:performance')
コード例 #22
0
ファイル: helper.py プロジェクト: saily/weblate
def show_form_errors(request, form):
    """Show all form errors as a message."""
    for error in form.non_field_errors():
        messages.error(request, error)
    for field in form:
        for error in field.errors:
            messages.error(
                request,
                _('Error in parameter %(field)s: %(error)s') % {
                    'field': field.name,
                    'error': error
                }
            )
コード例 #23
0
ファイル: edit.py プロジェクト: saily/weblate
def perform_translation(unit, form, request):
    """Handle translation and stores it to a backend."""
    # Remember old checks
    oldchecks = set(
        unit.active_checks().values_list('check', flat=True)
    )

    # Run AutoFixes on user input
    if not unit.translation.is_template():
        new_target, fixups = fix_target(form.cleaned_data['target'], unit)
    else:
        new_target = form.cleaned_data['target']
        fixups = []

    # Save
    saved = unit.translate(
        request,
        new_target,
        form.cleaned_data['fuzzy']
    )

    # Warn about applied fixups
    if len(fixups) > 0:
        messages.info(
            request,
            _('Following fixups were applied to translation: %s') %
            ', '.join([force_text(f) for f in fixups])
        )

    # Get new set of checks
    newchecks = set(
        unit.active_checks().values_list('check', flat=True)
    )

    # Did we introduce any new failures?
    if saved and newchecks > oldchecks:
        # Show message to user
        messages.error(
            request,
            _(
                'Some checks have failed on your translation: {0}'
            ).format(
                ', '.join(
                    [force_text(CHECKS[check].name) for check in newchecks]
                )
            )
        )
        # Stay on same entry
        return False

    return True
コード例 #24
0
ファイル: source.py プロジェクト: saily/weblate
def edit_check_flags(request, pk):
    """Change source string check flags."""
    source = get_object_or_404(Source, pk=pk)

    if not can_edit_flags(request.user, source.subproject.project):
        raise PermissionDenied()

    form = CheckFlagsForm(request.POST)
    if form.is_valid():
        source.check_flags = form.cleaned_data['flags']
        source.save()
    else:
        messages.error(request, _('Failed to change check flags!'))
    return redirect_next(request.POST.get('next'), source.get_absolute_url())
コード例 #25
0
ファイル: source.py プロジェクト: saily/weblate
def edit_priority(request, pk):
    """Change source string priority."""
    source = get_object_or_404(Source, pk=pk)

    if not can_edit_priority(request.user, source.subproject.project):
        raise PermissionDenied()

    form = PriorityForm(request.POST)
    if form.is_valid():
        source.priority = form.cleaned_data['priority']
        source.save()
    else:
        messages.error(request, _('Failed to change a priority!'))
    return redirect_next(request.POST.get('next'), source.get_absolute_url())
コード例 #26
0
ファイル: views.py プロジェクト: daleathan/weblate
 def rate_wrap(request, *args, **kwargs):
     attempts = request.session.get('auth_attempts', 0)
     if request.method == 'POST':
         if attempts >= settings.AUTH_MAX_ATTEMPTS:
             rotate_token(request)
             if request.user.is_authenticated:
                 logout(request)
             messages.error(
                 request,
                 _('Too many attempts, you have been logged out!')
             )
             return redirect('login')
         request.session['auth_attempts'] = attempts + 1
     return function(request, *args, **kwargs)
コード例 #27
0
ファイル: views.py プロジェクト: dekoza/weblate
 def form_valid(self, form):
     if not check_perm(self.request.user, 'memory.edit', self.objects):
         raise PermissionDenied()
     try:
         TranslationMemory.import_file(
             self.request, form.cleaned_data['file'], **self.objects
         )
         messages.success(
             self.request,
             _('File processed, the entries will appear shortly.')
         )
     except MemoryImportError as error:
         messages.error(self.request, force_text(error))
     return super(UploadView, self).form_valid(form)
コード例 #28
0
ファイル: source.py プロジェクト: daleathan/weblate
def edit_context(request, pk):
    """Change source string context."""
    source = get_object_or_404(Source, pk=pk)

    if not request.user.has_perm('source.edit', source.component):
        raise PermissionDenied()

    form = ContextForm(request.POST)
    if form.is_valid():
        source.context = form.cleaned_data['context']
        source.save()
    else:
        messages.error(request, _('Failed to change a context!'))
    return redirect_next(request.POST.get('next'), source.get_absolute_url())
コード例 #29
0
ファイル: edit.py プロジェクト: nijel/weblate
def perform_suggestion(unit, form, request):
    """Handle suggesion saving."""
    if form.cleaned_data['target'][0] == '':
        messages.error(request, _('Your suggestion is empty!'))
        # Stay on same entry
        return False
    if not request.user.has_perm('suggestion.add', unit.translation):
        # Need privilege to add
        messages.error(
            request,
            _('You don\'t have privileges to add suggestions!')
        )
        # Stay on same entry
        return False
    if not request.user.is_authenticated:
        # Spam check
        if is_spam('\n'.join(form.cleaned_data['target']), request):
            messages.error(
                request,
                _('Your suggestion has been identified as spam!')
            )
            return False

    # Create the suggestion
    result = Suggestion.objects.add(
        unit,
        join_plural(form.cleaned_data['target']),
        request,
        request.user.has_perm('suggestion.vote', unit)
    )
    if not result:
        messages.error(request, _('Your suggestion already exists!'))
    return result
コード例 #30
0
ファイル: git.py プロジェクト: nijel/weblate
def execute_locked(request, obj, message, call, *args, **kwargs):
    """Helper function to catch possible lock exception."""
    try:
        result = call(*args, **kwargs)
        # With False the call is supposed to show errors on its own
        if result is None or result:
            messages.success(request, message)
    except Timeout as error:
        messages.error(
            request,
            _('Failed to lock the repository, another operation is in progress.')
        )
        report_error(error, request)

    return redirect_param(obj, '#repository')
コード例 #31
0
def trial(request):
    """Form for hosting request."""
    if not settings.OFFER_HOSTING:
        return redirect("home")

    plan = request.POST.get("plan", "enterprise")

    # Avoid frequent requests for a trial for same user
    if plan != "libre" and request.user.auditlog_set.filter(
            activity="trial").exists():
        messages.error(
            request,
            _("Seems you've already requested a trial period recently. "
              "Please contact us with your inquiry so we can find the "
              "best solution for you."),
        )
        return redirect(reverse("contact") + "?t=trial")

    if request.method == "POST":
        from weblate.billing.models import Billing, Plan

        AuditLog.objects.create(request.user, request, "trial")
        billing = Billing.objects.create(
            plan=Plan.objects.get(slug=plan),
            state=Billing.STATE_TRIAL,
            expiry=timezone.now() + timedelta(days=14),
        )
        billing.owners.add(request.user)
        messages.info(
            request,
            _("Your trial period is now up and running; "
              "create your translation project and start Weblating!"),
        )
        return redirect(reverse("create-project") + f"?billing={billing.pk}")

    return render(request, "accounts/trial.html", {"title": _("Gratis trial")})
コード例 #32
0
def change_project(request, project):
    obj = get_project(request, project)

    if not request.user.has_perm("project.edit", obj):
        raise Http404()

    if request.method == "POST":
        settings_form = ProjectSettingsForm(request, request.POST, instance=obj)
        if settings_form.is_valid():
            settings_form.save()
            messages.success(request, _("Settings saved"))
            return redirect("settings", project=obj.slug)
        else:
            messages.error(
                request, _("Invalid settings, please check the form for errors!")
            )
    else:
        settings_form = ProjectSettingsForm(request, instance=obj)

    return render(
        request,
        "project-settings.html",
        {"object": obj, "form": settings_form},
    )
コード例 #33
0
def change_component(request, project, component):
    obj = get_component(request, project, component)

    if not request.user.has_perm("component.edit", obj):
        raise Http404()

    if request.method == "POST":
        form = ComponentSettingsForm(request, request.POST, instance=obj)
        if form.is_valid():
            form.save()
            messages.success(request, _("Settings saved"))
            return redirect("settings", project=obj.project.slug, component=obj.slug)
        else:
            messages.error(
                request, _("Invalid settings, please check the form for errors!")
            )
            # Get a fresh copy of object, otherwise it will use unsaved changes
            # from the failed form
            obj = Component.objects.get(pk=obj.pk)
    else:
        form = ComponentSettingsForm(request, instance=obj)

    if obj.repo_needs_merge():
        messages.warning(
            request,
            _(
                "The repository is outdated, you might not get "
                "expected results until you update it."
            ),
        )

    return render(
        request,
        "component-settings.html",
        {"project": obj.project, "object": obj, "form": form},
    )
コード例 #34
0
ファイル: views.py プロジェクト: mfrasca/weblate
def mail_admins_contact(request, subject, message, context, sender, to):
    """Send a message to the admins, as defined by the ADMINS setting."""
    LOGGER.info(
        'contact form from %s',
        sender,
    )
    if not to and settings.ADMINS:
        to = [a[1] for a in settings.ADMINS]
    elif not settings.ADMINS:
        messages.error(request,
                       _('Message could not be sent to administrator!'))
        LOGGER.error('ADMINS not configured, can not send message!')
        return

    mail = EmailMultiAlternatives(
        '{0}{1}'.format(settings.EMAIL_SUBJECT_PREFIX, subject % context),
        message % context,
        to=to,
        headers={'Reply-To': sender},
    )

    mail.send(fail_silently=False)

    messages.success(request, _('Message has been sent to administrator.'))
コード例 #35
0
ファイル: views.py プロジェクト: mfrasca/weblate
def reset_password_set(request):
    """Perform actual password reset."""
    user = User.objects.get(pk=request.session['perform_reset'])
    if user.has_usable_password():
        request.session.flush()
        request.session.set_expiry(None)
        messages.error(request,
                       _('Password reset has been already completed!'))
        return redirect('login')
    if request.method == 'POST':
        form = SetPasswordForm(user, request.POST)
        if form.is_valid():
            request.session.set_expiry(None)
            form.save(request, delete_session=True)
            return redirect('login')
    else:
        form = SetPasswordForm(user)
    return render(
        request, 'accounts/reset.html', {
            'title': _('Password reset'),
            'form': form,
            'captcha_form': None,
            'second_stage': True,
        })
コード例 #36
0
def invite_user(request, project):
    """Invite user to a project."""
    obj, form = check_user_form(request,
                                project,
                                True,
                                form_class=InviteUserForm)

    if form is not None:
        try:
            user = form.save()
            obj.add_user(user)
            Change.objects.create(
                project=obj,
                action=Change.ACTION_INVITE_USER,
                user=request.user,
                details={'username': user.username},
            )
            send_invitation(request, obj, user)
            messages.success(request,
                             _('User has been invited to this project.'))
        except Group.DoesNotExist:
            messages.error(request, _('Failed to find group to add a user!'))

    return redirect('manage-access', project=obj.slug)
コード例 #37
0
def change_access(request, project):
    obj = get_project(request, project)

    if not request.user.has_perm('billing:project.permissions', obj):
        raise PermissionDenied()

    form = ProjectAccessForm(request.POST, instance=obj)

    if not form.is_valid():
        for error in form.errors:
            for message in form.errors[error]:
                messages.error(request, message)
    else:
        form.save()
        Change.objects.create(
            project=obj,
            action=Change.ACTION_ACCESS_EDIT,
            user=request.user,
            details={'access_control': obj.access_control},
        )
        messages.success(request,
                         _('Project access control has been changed.'))

    return redirect('manage-access', project=obj.slug)
コード例 #38
0
ファイル: edit.py プロジェクト: nijel/weblate
def comment(request, pk):
    """Add new comment."""
    scope = unit = get_object_or_404(Unit, pk=pk)
    component = unit.translation.component

    if not request.user.has_perm("comment.add", unit.translation):
        raise PermissionDenied()

    form = CommentForm(component.project, request.POST)

    if form.is_valid():
        # Is this source or target comment?
        if form.cleaned_data["scope"] in ("global", "report"):
            scope = unit.source_unit
        # Create comment object
        Comment.objects.add(scope, request, form.cleaned_data["comment"])
        # Add review label/flag
        if form.cleaned_data["scope"] == "report":
            if component.has_template():
                if scope.translated and not scope.readonly:
                    scope.translate(
                        request.user,
                        scope.target,
                        STATE_FUZZY,
                        change_action=Change.ACTION_MARKED_EDIT,
                    )
            else:
                label = component.project.label_set.get_or_create(
                    name=gettext_noop("Source needs review"),
                    defaults={"color": "red"})[0]
                scope.labels.add(label)
        messages.success(request, _("Posted new comment"))
    else:
        messages.error(request, _("Failed to add comment!"))

    return redirect_next(request.POST.get("next"), unit)
コード例 #39
0
def tools(request):
    emailform = TestMailForm(initial={'email': request.user.email})

    if request.method == 'POST':
        if 'email' in request.POST:
            emailform = TestMailForm(request.POST)
            if emailform.is_valid():
                try:
                    send_test_mail(**emailform.cleaned_data)
                    messages.success(request, _('Test e-mail sent.'))
                except Exception as error:
                    report_error(error, request)
                    messages.error(request,
                                   _('Could not send test e-mail: %s') % error)

    return render(
        request,
        "manage/tools.html",
        {
            'menu_items': MENU,
            'menu_page': 'tools',
            'email_form': emailform
        },
    )
コード例 #40
0
ファイル: edit.py プロジェクト: nijel/weblate
def handle_translate(request, unit, this_unit_url, next_unit_url):
    """Save translation or suggestion to database and backend."""
    form = TranslationForm(request.user, unit, request.POST)
    if not form.is_valid():
        show_form_errors(request, form)
        return None

    go_next = True

    if "suggest" in request.POST:
        go_next = perform_suggestion(unit, form, request)
    elif not request.user.has_perm("unit.edit", unit):
        if request.user.has_perm("unit.flag", unit):
            update_explanation(unit, form)
        else:
            messages.error(
                request, _("Insufficient privileges for saving translations."))
    else:
        go_next = perform_translation(unit, form, request)

    # Redirect to next entry
    if "save-stay" not in request.POST and go_next:
        return HttpResponseRedirect(next_unit_url)
    return HttpResponseRedirect(this_unit_url)
コード例 #41
0
ファイル: ssh.py プロジェクト: xiaozwu2018/weblate
def add_host_key(request, host, port=""):
    """Add host key for a host."""
    if not host:
        messages.error(request, _("Invalid host name given!"))
    else:
        cmdline = ["ssh-keyscan"]
        if port:
            cmdline.extend(["-p", str(port)])
        cmdline.append(host)
        try:
            result = subprocess.run(
                cmdline,
                env=get_clean_env(),
                check=True,
                universal_newlines=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            keys = []
            for key in result.stdout.splitlines():
                key = key.strip()
                if not is_key_line(key):
                    continue
                keys.append(key)
                host, keytype, fingerprint = parse_hosts_line(key)
                messages.warning(
                    request,
                    _(
                        "Added host key for %(host)s with fingerprint "
                        "%(fingerprint)s (%(keytype)s), "
                        "please verify that it is correct."
                    )
                    % {"host": host, "fingerprint": fingerprint, "keytype": keytype},
                )
            if not keys:
                messages.error(request, _("Failed to fetch public key for a host!"))
            with open(ssh_file(KNOWN_HOSTS), "a") as handle:
                for key in keys:
                    handle.write("{0}\n".format(key))
        except subprocess.CalledProcessError as exc:
            messages.error(
                request, _("Failed to get host key: %s") % exc.stderr or exc.stdout
            )
        except OSError as exc:
            messages.error(request, _("Failed to get host key: %s") % str(exc))
コード例 #42
0
def add_host_key(request):
    """Add host key for a host."""
    host = request.POST.get('host', '')
    port = request.POST.get('port', '')
    if len(host) == 0:
        messages.error(request, _('Invalid host name given!'))
    else:
        cmdline = ['ssh-keyscan']
        if port:
            cmdline.extend(['-p', port])
        cmdline.append(host)
        try:
            output = subprocess.check_output(
                cmdline,
                stderr=subprocess.STDOUT,
                env=get_clean_env(),
            )
            keys = []
            for key in output.decode('utf-8').splitlines():
                key = key.strip()
                if not is_key_line(key):
                    continue
                keys.append(key)
                host, keytype, fingerprint = parse_hosts_line(key)
                messages.warning(
                    request,
                    _('Added host key for %(host)s with fingerprint '
                      '%(fingerprint)s (%(keytype)s), '
                      'please verify that it is correct.') % {
                          'host': host,
                          'fingerprint': fingerprint,
                          'keytype': keytype,
                      })
            if len(keys) == 0:
                messages.error(request,
                               _('Failed to fetch public key for a host!'))
            with open(ssh_file(KNOWN_HOSTS), 'a') as handle:
                for key in keys:
                    handle.write('{0}\n'.format(key))
        except subprocess.CalledProcessError as exc:
            messages.error(request,
                           _('Failed to get host key: %s') % exc.output)
        except OSError as exc:
            messages.error(request, _('Failed to get host key: %s') % str(exc))
コード例 #43
0
ファイル: views.py プロジェクト: yurchor/weblate
    def post(self, request, **kwargs):
        self.object = self.get_object()
        if not request.user.has_perm("project.edit", self.project):
            raise PermissionDenied()

        if "name" in request.POST:
            form = self._form = FontGroupForm(request.POST,
                                              instance=self.object,
                                              project=self.project)
            if form.is_valid():
                instance = form.save(commit=False)
                try:
                    instance.validate_unique()
                    instance.save()
                    return redirect(self.object)
                except ValidationError:
                    messages.error(request,
                                   _("Entry by the same name already exists."))
            return self.get(request, **kwargs)
        if "language" in request.POST:
            form = self._form = FontOverrideForm(request.POST)
            if form.is_valid():
                instance = form.save(commit=False)
                instance.group = self.object
                try:
                    instance.validate_unique()
                    instance.save()
                    return redirect(self.object)
                except ValidationError:
                    messages.error(request,
                                   _("Entry by the same name already exists."))
            return self.get(request, **kwargs)
        if "override" in request.POST:
            try:
                self.object.fontoverride_set.filter(
                    pk=int(request.POST["override"])).delete()
                return redirect(self.object)
            except (ValueError, ObjectDoesNotExist):
                messages.error(request, _("No override found."))

        self.object.delete()
        messages.error(request, _("Font group deleted."))
        return redirect("fonts", project=self.project.slug)
コード例 #44
0
ファイル: edit.py プロジェクト: anurag1212/weblate
def check_suggest_permissions(request, mode, translation, suggestion):
    """Check permission for suggestion handling."""
    if mode in ('accept', 'accept_edit'):
        if not can_accept_suggestion(request.user, translation):
            messages.error(
                request, _('You do not have privilege to accept suggestions!'))
            return False
    elif mode == 'delete':
        if not can_delete_suggestion(request.user, translation, suggestion):
            messages.error(
                request, _('You do not have privilege to delete suggestions!'))
            return False
    elif mode in ('upvote', 'downvote'):
        if not can_vote_suggestion(request.user, translation):
            messages.error(
                request,
                _('You do not have privilege to vote for suggestions!'))
            return False
    return True
コード例 #45
0
def check_suggest_permissions(request, mode, translation, suggestion):
    """Check permission for suggestion handling."""
    user = request.user
    if mode in ('accept', 'accept_edit'):
        if not user.has_perm('suggestion.accept', translation):
            messages.error(
                request, _('You do not have privilege to accept suggestions!'))
            return False
    elif mode in ('delete', 'spam'):
        if not user.has_perm('suggestion.delete', suggestion, translation):
            messages.error(
                request, _('You do not have privilege to delete suggestions!'))
            return False
    elif mode in ('upvote', 'downvote'):
        if not user.has_perm('suggestion.vote', translation):
            messages.error(
                request,
                _('You do not have privilege to vote for suggestions!'))
            return False
    return True
コード例 #46
0
ファイル: edit.py プロジェクト: lacroixdavid1/weblate
def check_suggest_permissions(request, mode, unit, suggestion):
    """Check permission for suggestion handling."""
    user = request.user
    if mode in ("accept", "accept_edit"):
        if not user.has_perm("suggestion.accept", unit):
            messages.error(
                request, _("You do not have privilege to accept suggestions!"))
            return False
    elif mode in ("delete", "spam"):
        if not user.has_perm("suggestion.delete", suggestion):
            messages.error(
                request, _("You do not have privilege to delete suggestions!"))
            return False
    elif mode in ("upvote", "downvote"):
        if not user.has_perm("suggestion.vote", unit):
            messages.error(
                request,
                _("You do not have privilege to vote for suggestions!"))
            return False
    return True
コード例 #47
0
def handle_merge(translation, request, next_unit_url):
    '''
    Handles unit merging.
    '''
    if not can_translate(request.user, translation):
        messages.error(
            request,
            _('You don\'t have privileges to save translations!')
        )
        return

    mergeform = MergeForm(translation, request.GET)
    if not mergeform.is_valid():
        messages.error(
            request,
            _('Invalid merge request!')
        )
        return

    unit = mergeform.cleaned_data['unit']

    merged = Unit.objects.get(
        pk=mergeform.cleaned_data['merge']
    )

    if unit.checksum != merged.checksum:
        messages.error(
            request,
            _('Can not merge different messages!')
        )
    else:
        # Store unit
        unit.target = merged.target
        unit.fuzzy = merged.fuzzy
        saved = unit.save_backend(request)
        # Update stats if there was change
        if saved:
            request.user.profile.translated += 1
            request.user.profile.save()
        # Redirect to next entry
        return HttpResponseRedirect(next_unit_url)
コード例 #48
0
ファイル: edit.py プロジェクト: anurag1212/weblate
def perform_suggestion(unit, form, request):
    """Handle suggesion saving."""
    if form.cleaned_data['target'][0] == '':
        messages.error(request, _('Your suggestion is empty!'))
        # Stay on same entry
        return False
    elif not can_suggest(request.user, unit.translation):
        # Need privilege to add
        messages.error(request,
                       _('You don\'t have privileges to add suggestions!'))
        # Stay on same entry
        return False
    # Invite user to become translator if there is nobody else
    # and the project is accepting translations
    translation = unit.translation
    if (not translation.subproject.suggestion_voting
            or not translation.subproject.suggestion_autoaccept):
        recent_changes = Change.objects.content(True).filter(
            translation=translation, ).exclude(user=None)
        if not recent_changes.exists():
            messages.info(
                request,
                _('There is currently no active translator for this '
                  'translation, please consider becoming a translator '
                  'as your suggestion might otherwise remain unreviewed.'))
            messages.info(
                request,
                mark_safe('<a href="{0}">{1}</a>'.format(
                    escape(get_doc_url('user/translating')),
                    escape(
                        _('See our documentation for more information '
                          'on translating using Weblate.')),
                )))
    # Create the suggestion
    result = Suggestion.objects.add(
        unit, join_plural(form.cleaned_data['target']), request,
        can_vote_suggestion(request.user, unit.translation))
    if not result:
        messages.error(request, _('Your suggestion already exists!'))
    return result
コード例 #49
0
ファイル: edit.py プロジェクト: anurag1212/weblate
def handle_revert(translation, request, next_unit_url):
    if not can_translate(request.user, translation):
        messages.error(request,
                       _('You don\'t have privileges to save translations!'))
        return

    revertform = RevertForm(translation, request.GET)
    if not revertform.is_valid():
        messages.error(request, _('Invalid revert request!'))
        return

    unit = revertform.cleaned_data['unit']
    change = revertform.cleaned_data['revert_change']

    if change.target == "":
        messages.error(request, _('Can not revert to empty translation!'))
    else:
        # Store unit
        unit.target = change.target
        unit.save_backend(request, change_action=Change.ACTION_REVERT)
        # Redirect to next entry
        return HttpResponseRedirect(next_unit_url)
コード例 #50
0
def handle_revert(translation, request, next_unit_url):
    revertform = RevertForm(translation, request.GET)
    if not revertform.is_valid():
        messages.error(request, _('Invalid revert request!'))
        return None

    unit = revertform.cleaned_data['unit']
    change = revertform.cleaned_data['revert_change']

    if not request.user.has_perm('unit.edit', unit):
        messages.error(request, _('Insufficient privileges for saving translations.'))
        return None

    if not change.can_revert():
        messages.error(request, _('Can not revert to empty translation!'))
        return None
    # Store unit
    unit.translate(
        request.user, change.old, unit.state, change_action=Change.ACTION_REVERT
    )
    # Redirect to next entry
    return HttpResponseRedirect(next_unit_url)
コード例 #51
0
def perform_suggestion(unit, form, request):
    '''
    Handle suggesion saving.
    '''
    if form.cleaned_data['target'][0] == '':
        messages.error(request, _('Your suggestion is empty!'))
        # Stay on same entry
        return False
    elif not can_suggest(request.user, unit.translation):
        # Need privilege to add
        messages.error(
            request,
            _('You don\'t have privileges to add suggestions!')
        )
        # Stay on same entry
        return False
    # Invite user to become translator if there is nobody else
    recent_changes = Change.objects.content(True).filter(
        translation=unit.translation,
    ).exclude(
        user=None
    )
    if not recent_changes.exists():
        messages.info(request, _(
            'There is currently no active translator for this '
            'translation, please consider becoming a translator '
            'as your suggestion might otherwise remain unreviewed.'
        ))
    # Create the suggestion
    result = Suggestion.objects.add(
        unit,
        join_plural(form.cleaned_data['target']),
        request,
    )
    if not result:
        messages.error(request, _('Your suggestion already exists!'))
    return result
コード例 #52
0
def handle_revert(unit, request, next_unit_url):
    revertform = RevertForm(unit, request.GET)
    if not revertform.is_valid():
        messages.error(request, _("Invalid revert request!"))
        return None

    change = revertform.cleaned_data["revert_change"]

    if not request.user.has_perm("unit.edit", unit):
        messages.error(request, _("Insufficient privileges for saving translations."))
        return None

    if not change.can_revert():
        messages.error(request, _("Can not revert to empty translation!"))
        return None
    # Store unit
    unit.translate(
        request.user,
        change.old,
        STATE_FUZZY if change.action == Change.ACTION_MARKED_EDIT else unit.state,
        change_action=Change.ACTION_REVERT,
    )
    # Redirect to next entry
    return HttpResponseRedirect(next_unit_url)
コード例 #53
0
def auth_fail(request, message):
    messages.error(request, message)
    return redirect(reverse('login'))
コード例 #54
0
    def save_backend(self,
                     request,
                     propagate=True,
                     gen_change=True,
                     change_action=None,
                     user=None):
        """
        Stores unit to backend.

        Optional user parameters defines authorship of a change.
        """
        # For case when authorship specified, use user from request
        if user is None or user.is_anonymous:
            user = request.user

        # Update lock timestamp
        self.update_lock(request, user, change_action)

        # Store to backend
        try:
            (saved, pounit) = self.translation.update_unit(self, request, user)
        except FileLockException:
            self.log_error('failed to lock backend for %s!', self)
            messages.error(
                request,
                _('Failed to store message in the backend, '
                  'lock timeout occurred!'))
            return False

        # Handle situation when backend did not find the message
        if pounit is None:
            self.log_error('message %s disappeared!', self)
            messages.error(
                request,
                _('Message not found in backend storage, '
                  'it is probably corrupted.'))
            # Try reloading from backend
            self.translation.check_sync(True)
            return False

        # Return if there was no change
        # We have to explicitly check for fuzzy flag change on monolingual
        # files, where we handle it ourselves without storing to backend
        if (not saved and self.old_unit.fuzzy == self.fuzzy
                and self.old_unit.target == self.target):
            # Propagate if we should
            if propagate:
                self.propagate(request, change_action)
            return False

        # Update translated flag
        self.translated = pounit.is_translated()

        # Update comments as they might have been changed (eg, fuzzy flag
        # removed)
        self.flags = pounit.get_flags()

        if self.translation.is_template():
            self.source = self.target
            self.content_hash = calculate_hash(self.source, self.context)

        # Save updated unit to database
        self.save(backend=True)

        # Update translation stats
        old_translated = self.translation.translated
        if change_action != Change.ACTION_UPLOAD:
            self.translation.update_stats()

        # Notify subscribed users about new translation
        notify_new_translation(self, self.old_unit, user)

        # Update user stats
        user.profile.translated += 1
        user.profile.save()

        # Generate Change object for this change
        if gen_change:
            self.generate_change(request, user, self.old_unit, change_action)

        # Force commiting on completing translation
        if (old_translated < self.translation.translated
                and self.translation.translated == self.translation.total):
            self.translation.commit_pending(request)
            Change.objects.create(translation=self.translation,
                                  action=Change.ACTION_COMPLETE,
                                  user=user,
                                  author=user)

        # Update related source strings if working on a template
        if self.translation.is_template():
            self.update_source_units(self.old_unit.source)

        # Propagate to other projects
        if propagate:
            self.propagate(request, change_action)

        return True
コード例 #55
0
ファイル: edit.py プロジェクト: lacroixdavid1/weblate
def translate(request, project, component, lang):
    """Generic entry point for translating, suggesting and searching."""
    obj, project, unit_set = parse_params(request, project, component, lang)

    # Search results
    search_result = search(obj, unit_set, request)

    # Handle redirects
    if isinstance(search_result, HttpResponse):
        return search_result

    # Get numer of results
    num_results = len(search_result["ids"])

    # Search offset
    offset = search_result["offset"]

    # Checksum unit access
    checksum_form = ChecksumForm(unit_set, request.GET or request.POST)
    if checksum_form.is_valid():
        unit = checksum_form.cleaned_data["unit"]
        try:
            offset = search_result["ids"].index(unit.id) + 1
        except ValueError:
            messages.warning(request, _("No string matched your search!"))
            return redirect(obj)
    else:
        # Check boundaries
        if not 0 < offset <= num_results:
            messages.info(request, _("The translation has come to an end."))
            # Delete search
            del request.session[search_result["key"]]
            return redirect(obj)

        # Grab actual unit
        try:
            unit = unit_set.get(pk=search_result["ids"][offset - 1])
        except Unit.DoesNotExist:
            # Can happen when using SID for other translation
            messages.error(request, _("Invalid search string!"))
            return redirect(obj)

    # Check locks
    locked = unit.translation.component.locked

    # Some URLs we will most likely use
    base_unit_url = "{}?{}&offset=".format(obj.get_translate_url(),
                                           search_result["url"])
    this_unit_url = base_unit_url + str(offset)
    next_unit_url = base_unit_url + str(offset + 1)

    response = None

    # Any form submitted?
    if "skip" in request.POST:
        return redirect(next_unit_url)
    if request.method == "POST" and "merge" not in request.POST:
        if (not locked and "accept" not in request.POST
                and "accept_edit" not in request.POST
                and "delete" not in request.POST and "spam" not in request.POST
                and "upvote" not in request.POST
                and "downvote" not in request.POST):
            # Handle translation
            response = handle_translate(request, unit, this_unit_url,
                                        next_unit_url)
        elif not locked or "delete" in request.POST or "spam" in request.POST:
            # Handle accepting/deleting suggestions
            response = handle_suggestions(request, unit, this_unit_url,
                                          next_unit_url)

    # Handle translation merging
    elif "merge" in request.POST and not locked:
        response = handle_merge(unit, request, next_unit_url)

    # Handle reverting
    elif "revert" in request.GET and not locked:
        response = handle_revert(unit, request, this_unit_url)

    # Pass possible redirect further
    if response is not None:
        return response

    # Show secondary languages for signed in users
    if request.user.is_authenticated:
        secondary = unit.get_secondary_units(request.user)
    else:
        secondary = None

    # Spam protection
    antispam = AntispamForm()

    # Prepare form
    form = TranslationForm(request.user, unit)
    sort = get_sort_name(request)

    return render(
        request,
        "translate.html",
        {
            "this_unit_url":
            this_unit_url,
            "first_unit_url":
            base_unit_url + "1",
            "last_unit_url":
            base_unit_url + str(num_results),
            "next_unit_url":
            next_unit_url,
            "prev_unit_url":
            base_unit_url + str(offset - 1),
            "object":
            obj,
            "project":
            project,
            "unit":
            unit,
            "nearby":
            unit.nearby(request.user.profile.nearby_strings),
            "nearby_keys":
            unit.nearby_keys(request.user.profile.nearby_strings),
            "others":
            get_other_units(unit),
            "search_url":
            search_result["url"],
            "search_items":
            search_result["items"],
            "search_query":
            search_result["query"],
            "offset":
            offset,
            "sort_name":
            sort["name"],
            "sort_query":
            sort["query"],
            "filter_name":
            search_result["name"],
            "filter_count":
            num_results,
            "filter_pos":
            offset,
            "form":
            form,
            "antispam":
            antispam,
            "comment_form":
            CommentForm(
                project,
                initial={
                    "scope": "global" if unit.is_source else "translation"
                },
            ),
            "context_form":
            ContextForm(instance=unit.source_unit, user=request.user),
            "search_form":
            search_result["form"].reset_offset(),
            "secondary":
            secondary,
            "locked":
            locked,
            "glossary":
            Term.objects.get_terms(unit),
            "addterm_form":
            TermForm(project),
            "last_changes":
            unit.change_set.prefetch().order()[:10],
            "screenshots": (unit.source_unit.screenshots.all()
                            | unit.screenshots.all()).order,
            "last_changes_url":
            urlencode(unit.translation.get_reverse_url_kwargs()),
            "display_checks":
            list(get_display_checks(unit)),
            "machinery_services":
            json.dumps(list(MACHINE_TRANSLATION_SERVICES.keys())),
        },
    )
コード例 #56
0
ファイル: edit.py プロジェクト: wade1990/weblate
def translate(request, project, component, lang):
    """Generic entry point for translating, suggesting and searching."""
    translation = get_translation(request, project, component, lang)

    # Check locks
    locked = translation.component.locked

    # Search results
    search_result = search(translation, request)

    # Handle redirects
    if isinstance(search_result, HttpResponse):
        return search_result

    # Get numer of results
    num_results = len(search_result['ids'])

    # Search offset
    offset = search_result['offset']

    # Checksum unit access
    if search_result['checksum']:
        try:
            unit = translation.unit_set.get(id_hash=search_result['checksum'])
            offset = search_result['ids'].index(unit.id) + 1
        except (Unit.DoesNotExist, ValueError):
            messages.warning(request, _('No string matched your search!'))
            return redirect(translation)

    # Check boundaries
    if not 0 < offset <= num_results:
        messages.info(request, _('The translation has come to an end.'))
        # Delete search
        del request.session[search_result['key']]
        # Redirect to translation
        return redirect(translation)

    # Some URLs we will most likely use
    base_unit_url = '{0}?{1}&offset='.format(
        translation.get_translate_url(),
        search_result['url']
    )
    this_unit_url = base_unit_url + str(offset)
    next_unit_url = base_unit_url + str(offset + 1)

    response = None

    # Any form submitted?
    if 'skip' in request.POST:
        return redirect(next_unit_url)
    if request.method == 'POST':
        if (not locked
                and 'accept' not in request.POST
                and 'accept_edit' not in request.POST
                and 'delete' not in request.POST
                and 'spam' not in request.POST
                and 'upvote' not in request.POST
                and 'downvote' not in request.POST):
            # Handle translation
            response = handle_translate(
                request, translation, this_unit_url, next_unit_url
            )
        elif not locked or 'delete' in request.POST or 'spam' in request.POST:
            # Handle accepting/deleting suggestions
            response = handle_suggestions(
                translation, request, this_unit_url, next_unit_url,
            )

    # Handle translation merging
    elif 'merge' in request.GET and not locked:
        response = handle_merge(
            translation, request, next_unit_url
        )

    # Handle reverting
    elif 'revert' in request.GET and not locked:
        response = handle_revert(
            translation, request, this_unit_url
        )

    # Pass possible redirect further
    if response is not None:
        return response

    # Grab actual unit
    try:
        unit = translation.unit_set.get(pk=search_result['ids'][offset - 1])
    except Unit.DoesNotExist:
        # Can happen when using SID for other translation
        messages.error(request, _('Invalid search string!'))
        return redirect(translation)

    # Show secondary languages for logged in users
    if request.user.is_authenticated:
        secondary = unit.get_secondary_units(request.user)
    else:
        secondary = None

    # Spam protection
    antispam = AntispamForm()

    # Prepare form
    form = TranslationForm(request.user, translation, unit)

    return render(
        request,
        'translate.html',
        {
            'this_unit_url': this_unit_url,
            'first_unit_url': base_unit_url + '1',
            'last_unit_url': base_unit_url + str(num_results),
            'next_unit_url': next_unit_url,
            'prev_unit_url': base_unit_url + str(offset - 1),
            'object': translation,
            'project': translation.component.project,
            'unit': unit,
            'others': get_other_units(unit),
            'total': translation.unit_set.all().count(),
            'search_url': search_result['url'],
            'search_items': search_result['items'],
            'search_query': search_result['query'],
            'offset': offset,
            'filter_name': search_result['name'],
            'filter_count': num_results,
            'filter_pos': offset,
            'form': form,
            'antispam': antispam,
            'comment_form': CommentForm(),
            'search_form': search_result['form'].reset_offset(),
            'secondary': secondary,
            'locked': locked,
            'glossary': Dictionary.objects.get_words(unit),
            'addword_form': InlineWordForm(),
        }
    )
コード例 #57
0
ファイル: views.py プロジェクト: tsoslow/weblate
 def redirect_list(self, message=None):
     if message:
         messages.error(self.request, message)
     return redirect(self.get_success_url())
コード例 #58
0
ファイル: search.py プロジェクト: roptat/weblate
def search(request, project=None, component=None, lang=None):
    """Perform site-wide search on units."""
    is_ratelimited = not check_rate_limit("search", request)
    search_form = SearchForm(user=request.user, data=request.GET)
    sort = get_sort_name(request)
    context = {"search_form": search_form}
    if component:
        obj = get_component(request, project, component)
        context["component"] = obj
        context["project"] = obj.project
        context["back_url"] = obj.get_absolute_url()
    elif project:
        obj = get_project(request, project)
        context["project"] = obj
        context["back_url"] = obj.get_absolute_url()
    else:
        obj = None
        context["back_url"] = None
    if lang:
        s_language = get_object_or_404(Language, code=lang)
        context["language"] = s_language
        if obj:
            if component:
                context["back_url"] = obj.translation_set.get(
                    language=s_language).get_absolute_url()
            else:
                context["back_url"] = reverse("project-language",
                                              kwargs={
                                                  "project": project,
                                                  "lang": lang
                                              })
        else:
            context["back_url"] = s_language.get_absolute_url()

    if not is_ratelimited and request.GET and search_form.is_valid():
        # This is ugly way to hide query builder when showing results
        search_form = SearchForm(user=request.user,
                                 data=request.GET,
                                 show_builder=False)
        search_form.is_valid()
        # Filter results by ACL
        units = Unit.objects.prefetch_full().prefetch()
        if component:
            units = units.filter(translation__component=obj)
        elif project:
            units = units.filter(translation__component__project=obj)
        else:
            units = units.filter_access(request.user)
        units = units.search(search_form.cleaned_data.get("q", ""),
                             project=context.get("project")).distinct()
        if lang:
            units = units.filter(translation__language=context["language"])

        units = get_paginator(request,
                              units.order_by_request(search_form.cleaned_data))
        # Rebuild context from scratch here to get new form
        context = {
            "search_form": search_form,
            "show_results": True,
            "page_obj": units,
            "title": _("Search for %s") % (search_form.cleaned_data["q"]),
            "query_string": search_form.urlencode(),
            "search_query": search_form.cleaned_data["q"],
            "search_items": search_form.items(),
            "filter_name": search_form.get_name(),
            "sort_name": sort["name"],
            "sort_query": sort["query"],
        }
    elif is_ratelimited:
        messages.error(request,
                       _("Too many search queries, please try again later."))
    elif request.GET:
        messages.error(request, _("Invalid search query!"))
        show_form_errors(request, search_form)

    return render(request, "search.html", context)
コード例 #59
0
ファイル: search.py プロジェクト: roptat/weblate
def search_replace(request, project, component=None, lang=None):
    obj, unit_set, context = parse_url(request, project, component, lang)

    form = ReplaceForm(request.POST)

    if not form.is_valid():
        messages.error(request, _("Failed to process form!"))
        show_form_errors(request, form)
        return redirect(obj)

    search_text = form.cleaned_data["search"]
    replacement = form.cleaned_data["replacement"]

    matching = unit_set.filter(target__contains=search_text)

    updated = 0
    if matching.exists():
        confirm = ReplaceConfirmForm(matching, request.POST)
        limited = False

        if matching.count() > 300:
            matching = matching.order_by("id")[:250]
            limited = True

        if not confirm.is_valid():
            for unit in matching:
                unit.replacement = unit.target.replace(search_text,
                                                       replacement)
            context.update({
                "matching": matching,
                "search_query": search_text,
                "replacement": replacement,
                "form": form,
                "limited": limited,
                "confirm": ReplaceConfirmForm(matching),
            })
            return render(request, "replace.html", context)

        matching = confirm.cleaned_data["units"]

        with transaction.atomic():
            for unit in matching.select_for_update(**get_nokey_args()):
                if not request.user.has_perm("unit.edit", unit):
                    continue
                unit.translate(
                    request.user,
                    unit.target.replace(search_text, replacement),
                    unit.state,
                    change_action=Change.ACTION_REPLACE,
                )
                updated += 1

    import_message(
        request,
        updated,
        _("Search and replace completed, no strings were updated."),
        ngettext(
            "Search and replace completed, %d string was updated.",
            "Search and replace completed, %d strings were updated.",
            updated,
        ),
    )

    return redirect(obj)
コード例 #60
0
def upload_translation(request, project, subproject, lang):
    '''
    Handling of translation uploads.
    '''
    obj = get_translation(request, project, subproject, lang)

    if not can_upload_translation(request.user, obj):
        raise PermissionDenied()

    # Check method and lock
    if obj.is_locked(request.user):
        messages.error(request, _('Access denied.'))
        return redirect(obj)

    # Get correct form handler based on permissions
    form = get_upload_form(
        request.user, obj,
        request.POST, request.FILES
    )

    # Check form validity
    if not form.is_valid():
        messages.error(request, _('Please fix errors in the form.'))
        show_form_errors(request, form)
        return redirect(obj)

    # Create author name
    author = None
    if (can_author_translation(request.user, obj.subproject.project) and
            form.cleaned_data['author_name'] != '' and
            form.cleaned_data['author_email'] != ''):
        author = '%s <%s>' % (
            form.cleaned_data['author_name'],
            form.cleaned_data['author_email']
        )

    # Check for overwriting
    overwrite = False
    if can_overwrite_translation(request.user, obj.subproject.project):
        overwrite = form.cleaned_data['overwrite']

    # Do actual import
    try:
        ret, count = obj.merge_upload(
            request,
            request.FILES['file'],
            overwrite,
            author,
            merge_header=form.cleaned_data['merge_header'],
            merge_comments=form.cleaned_data['merge_comments'],
            method=form.cleaned_data['method'],
            fuzzy=form.cleaned_data['fuzzy'],
        )
        import_message(
            request, count,
            _('No strings were imported from the uploaded file.'),
            ungettext(
                'Processed %d string from the uploaded files.',
                'Processed %d strings from the uploaded files.',
                count
            )
        )
        if not ret:
            messages.warning(
                request,
                _('There were no new strings in uploaded file!')
            )
    except Exception as error:
        messages.error(
            request, _('File content merge failed: %s') % force_text(error)
        )
        report_error(error, sys.exc_info(), request)

    return redirect(obj)