Beispiel #1
0
def new_unit(request, project, component, lang):
    translation = get_translation(request, project, component, lang)
    if not request.user.has_perm("unit.add", translation):
        raise PermissionDenied()

    form = get_new_unit_form(translation, request.user, request.POST)
    if not form.is_valid():
        show_form_errors(request, form)
    else:
        if form.unit_exists(translation):
            messages.error(request, _("This string seems to already exist."))
        else:
            # This is slow way of detecting unit, add_units should directly
            # create the database units, return them and they should be saved to
            # file as regular pending ones.
            existing = list(translation.unit_set.values_list("pk", flat=True))
            translation.add_units(request, [form.as_tuple()])
            messages.success(request, _("New string has been added."))
            new_units = translation.unit_set.exclude(pk__in=existing)
            if form.cleaned_data["variant"]:
                for new_unit in new_units:
                    flags = Flags(new_unit.extra_flags)
                    flags.set_value("variant", form.cleaned_data["variant"])
                    new_unit.extra_flags = flags.format()
                    new_unit.save(
                        update_fields=["extra_flags"],
                        same_content=True,
                        run_checks=False,
                    )
                    return redirect(new_unit)

    return redirect(translation)
Beispiel #2
0
def validate_check_flags(val):
    """Validate check influencing flags."""
    try:
        flags = Flags(val)
    except ParseException as error:
        raise ValidationError(_("Failed to parse flags: %s") % error)
    flags.validate()
Beispiel #3
0
 def test_unicode(self):
     self.assertEqual(
         Flags("zkouška, Memóriakártya").items(),
         {"zkouška", "Memóriakártya"})
     self.assertEqual(
         Flags("placeholder:'zkouška sirén'").items(),
         {("placeholder", "zkouška sirén")},
     )
Beispiel #4
0
 def test_quoted_values(self):
     flags = Flags(r"""placeholders:"bar: \"value\"":'baz \'value\''""")
     self.assertEqual(
         flags.get_value("placeholders"), ['bar: "value"', "baz 'value'"]
     )
     self.assertEqual(
         flags.format(), r'''placeholders:"bar: \"value\"":"baz 'value'"'''
     )
Beispiel #5
0
    def sync_terminology(self):
        try:
            unit_flags = Flags(self.flags)
        except ParseException:
            unit_flags = None
        new_flags = Flags(self.extra_flags, unit_flags)

        if "terminology" in new_flags:
            self.translation.component.schedule_sync_terminology()
Beispiel #6
0
 def post_uninstall(self):
     try:
         target_translation = self.get_target_translation(self.instance.component)
         flags = Flags(target_translation.check_flags)
         flags.remove("ignore-all-checks")
         target_translation.check_flags = flags.format()
         target_translation.save(update_fields=["check_flags"])
     except Translation.DoesNotExist:
         pass
     super().post_uninstall()
Beispiel #7
0
 def post_configure(self, run: bool = True):
     try:
         target_translation = self.get_target_translation(self.instance.component)
         flags = Flags(target_translation.check_flags)
         flags.merge("ignore-all-checks")
         target_translation.check_flags = flags.format()
         target_translation.save(update_fields=["check_flags"])
     except Translation.DoesNotExist:
         pass
     super().post_configure(run=run)
Beispiel #8
0
def bulk_edit(request, project, component=None, lang=None):
    obj, unit_set, context = parse_url(request, project, component, lang)

    if not request.user.has_perm('translation.auto', obj):
        raise PermissionDenied()

    form = BulkEditForm(request.user, obj, request.POST, project=context['project'])

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

    target_state = int(form.cleaned_data['state'])
    add_flags = Flags(form.cleaned_data['add_flags'])
    remove_flags = Flags(form.cleaned_data['remove_flags'])
    add_labels = form.cleaned_data['add_labels']
    remove_labels = form.cleaned_data['remove_labels']

    matching = unit_set.search(form.cleaned_data['q'])

    updated = 0
    with transaction.atomic():
        for unit in matching.select_for_update():
            if not request.user.has_perm('unit.edit', unit):
                continue
            if target_state != -1 and unit.state:
                unit.translate(
                    request.user,
                    unit.target,
                    target_state,
                    change_action=Change.ACTION_MASS_STATE,
                )
                updated += 1
            if add_flags or remove_flags:
                flags = Flags(unit.source_info.extra_flags)
                flags.merge(add_flags)
                flags.remove(remove_flags)
                unit.source_info.extra_flags = flags.format()
                unit.source_info.save(update_fields=['extra_flags'])
                updated += 1
            if add_labels:
                unit.source_info.labels.add(*add_labels)
                updated += 1
            if remove_labels:
                unit.source_info.labels.remove(*remove_labels)
                updated += 1

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

    return redirect(obj)
Beispiel #9
0
def bulk_perform(
    user,
    unit_set,
    query,
    target_state,
    add_flags,
    remove_flags,
    add_labels,
    remove_labels,
):
    matching = unit_set.search(query)

    target_state = int(target_state)
    add_flags = Flags(add_flags)
    remove_flags = Flags(remove_flags)

    cleanups = {}
    preloaded_sources = False

    updated = 0
    with transaction.atomic():
        for unit in matching.select_for_update():
            if not preloaded_sources:
                unit.translation.component.preload_sources()
                preloaded_sources = True
            if user is not None and not user.has_perm("unit.edit", unit):
                continue
            updated += 1
            if (target_state != -1 and unit.state > STATE_EMPTY
                    and unit.state < STATE_READONLY):
                unit.translate(
                    user,
                    unit.target,
                    target_state,
                    change_action=Change.ACTION_BULK_EDIT,
                    propagate=False,
                )
            if add_flags or remove_flags:
                flags = Flags(unit.source_info.extra_flags)
                flags.merge(add_flags)
                flags.remove(remove_flags)
                unit.source_info.is_bulk_edit = True
                unit.source_info.extra_flags = flags.format()
                unit.source_info.save(update_fields=["extra_flags"])
                cleanups[
                    unit.translation.component.pk] = unit.translation.component
            if add_labels:
                unit.source_info.is_bulk_edit = True
                unit.source_info.labels.add(*add_labels)
                cleanups[
                    unit.translation.component.pk] = unit.translation.component
            if remove_labels:
                unit.source_info.is_bulk_edit = True
                unit.source_info.labels.remove(*remove_labels)
                cleanups[
                    unit.translation.component.pk] = unit.translation.component
    for component in cleanups.values():
        component.invalidate_stats_deep()
    return updated
Beispiel #10
0
    def update_variants(self):
        old_flags = Flags(self.old_unit.extra_flags, self.old_unit.flags)
        new_flags = Flags(self.extra_flags, self.flags)

        old_variant = None
        if old_flags.has_value("variant"):
            old_variant = old_flags.get_value("variant")
        new_variant = None
        if new_flags.has_value("variant"):
            new_variant = new_flags.get_value("variant")

        # Check for relevant changes
        if old_variant == new_variant:
            return

        # Delete stale variant
        if old_variant:
            for variant in self.defined_variants.all():
                variant.defining_units.remove(self)
                if variant.defining_units.count() == 0:
                    variant.delete()
                else:
                    variant.unit_set.filter(id_hash=self.id_hash).update(
                        variant=None)

        # Add new variant
        if new_variant:
            variant = Variant.objects.get_or_create(
                key=new_variant, component=self.translation.component)[0]
            variant.defining_units.add(self)

        # Update variant links
        self.translation.component.update_variants()
Beispiel #11
0
 def test_whitespace(self):
     self.assertEqual(Flags("  foo    , bar  ").items(), {"foo", "bar"})
     flags = Flags(
         "max-size:120:2,font-family:DIN next pro,font-spacing:2, priority:140"
     )
     self.assertEqual(
         flags.items(),
         {
             ("font-family", "DIN next pro"),
             ("priority", "140"),
             ("max-size", "120", "2"),
             ("font-spacing", "2"),
         },
     )
Beispiel #12
0
 def test_remove(self):
     flags = Flags("placeholders:bar:baz, foo:1, bar")
     flags.remove("foo")
     self.assertEqual(flags.items(),
                      {("placeholders", "bar", "baz"), "bar"})
     flags.remove("bar")
     self.assertEqual(flags.items(), {("placeholders", "bar", "baz")})
Beispiel #13
0
    def get_all_flags(self, override=None):
        """Return union of own and component flags."""
        # Validate flags from the unit to avoid crash
        try:
            unit_flags = Flags(override or self.flags)
        except ParseException:
            unit_flags = None

        return Flags(
            self.translation.all_flags,
            self.extra_flags,
            # The source_unit is None before saving the object for the first time
            getattr(self.source_unit, "extra_flags", ""),
            unit_flags,
        )
Beispiel #14
0
def bulk_perform(
    user,
    unit_set,
    query,
    target_state,
    add_flags,
    remove_flags,
    add_labels,
    remove_labels,
):
    matching = unit_set.search(query)
    components = Component.objects.filter(
        id__in=matching.values_list("translation__component_id", flat=True))

    target_state = int(target_state)
    add_flags = Flags(add_flags)
    remove_flags = Flags(remove_flags)

    updated = 0
    for component in components:
        component.preload_sources()
        with transaction.atomic(), component.lock():
            for unit in matching.filter(
                    translation__component=component).select_for_update():
                if user is not None and not user.has_perm("unit.edit", unit):
                    continue
                updated += 1
                if (target_state != -1 and unit.state > STATE_EMPTY
                        and unit.state < STATE_READONLY):
                    unit.translate(
                        user,
                        unit.target,
                        target_state,
                        change_action=Change.ACTION_BULK_EDIT,
                        propagate=False,
                    )
                if add_flags or remove_flags:
                    flags = Flags(unit.source_info.extra_flags)
                    flags.merge(add_flags)
                    flags.remove(remove_flags)
                    unit.source_info.is_bulk_edit = True
                    unit.source_info.extra_flags = flags.format()
                    unit.source_info.save(update_fields=["extra_flags"])
                if add_labels:
                    unit.source_info.is_bulk_edit = True
                    unit.source_info.labels.add(*add_labels)
                if remove_labels:
                    unit.source_info.is_bulk_edit = True
                    unit.source_info.labels.remove(*remove_labels)

        component.invalidate_stats_deep()

    return updated
Beispiel #15
0
 def get_all_flags(self, override=None):
     """Return union of own and component flags."""
     return Flags(
         self.translation.all_flags,
         self.extra_flags,
         override or self.flags,
     )
Beispiel #16
0
 def get_all_flags(self, override=None):
     """Return union of own and component flags."""
     return Flags(
         self.translation.component.all_flags,
         self.source_info.check_flags,
         override or self.flags,
     )
Beispiel #17
0
 def all_flags(self):
     """Return union of own and component flags."""
     return Flags(
         self.translation.component.all_flags,
         self.source_info.check_flags,
         self.flags,
     )
Beispiel #18
0
 def flags(self):
     placeholders = self.mainunit.placeholders
     if not placeholders:
         return ""
     return "placeholders:{}".format(":".join(
         Flags.format_value("{{{}}}".format(key.upper()))
         for key in placeholders.keys()))
Beispiel #19
0
 def test_description(self):
     unit = Unit(source="string URL", target="string")
     unit.__dict__["all_flags"] = Flags("regex:URL")
     check = Check(unit=unit)
     self.assertEqual(
         self.check.get_description(check),
         "Does not match regular expression <code>URL</code>.",
     )
Beispiel #20
0
 def test_description(self):
     unit = Unit(source="string $URL$", target="string")
     unit.__dict__["all_flags"] = Flags("placeholders:$URL$")
     check = Check(unit=unit)
     self.assertEqual(
         self.check.get_description(check),
         "Translation is missing some placeholders: $URL$",
     )
Beispiel #21
0
 def test_description(self):
     unit = Unit(source="string $URL$", target="string")
     unit.__dict__["all_flags"] = Flags("placeholders:$URL$")
     check = Check(unit=unit)
     self.assertEqual(
         self.check.get_description(check),
         "Following format strings are missing: $URL$",
     )
Beispiel #22
0
 def get_all_flags(self, override=None):
     """Return union of own and component flags."""
     return Flags(
         self.translation.all_flags,
         # The source_unit is None before saving the object for the first time
         self.source_unit.extra_flags if self.source_unit else self.extra_flags,
         override or self.flags,
     )
Beispiel #23
0
def edit_context(request, pk):
    unit = get_object_or_404(Unit, pk=pk)
    if not unit.is_source and not unit.translation.component.is_glossary:
        raise Http404("Non source unit!")

    do_add = "addflag" in request.POST
    if do_add or "removeflag" in request.POST:
        if not request.user.has_perm("unit.flag", unit.translation):
            raise PermissionDenied()
        flag = request.POST.get("addflag", request.POST.get("removeflag"))
        flags = Flags(unit.extra_flags)
        if do_add:
            flags.merge(flag)
        else:
            flags.remove(flag)
        new_flags = flags.format()
        if new_flags != unit.extra_flags:
            unit.extra_flags = new_flags
            unit.save(same_content=True, update_fields=["extra_flags"])
    else:

        if not request.user.has_perm("source.edit", unit.translation):
            raise PermissionDenied()

        form = ContextForm(request.POST, instance=unit, user=request.user)

        if form.is_valid():
            form.save()
        else:
            messages.error(request,
                           _("Failed to change additional string info!"))
            show_form_errors(request, form)

    return redirect_next(request.POST.get("next"), unit.get_absolute_url())
Beispiel #24
0
 def test_regexp(self):
     unit = Unit(source="string $URL$", target="string $FOO$")
     unit.__dict__["all_flags"] = Flags(r"""placeholders:r"\$[^$]*\$" """)
     check = Check(unit=unit)
     self.assertEqual(
         self.check.get_description(check),
         "Following format strings are missing: $URL$"
         "<br />Following format strings are extra: $FOO$",
     )
Beispiel #25
0
def ignore_check_source(request, check_id):
    obj = get_object_or_404(Check, pk=int(check_id))
    unit = obj.unit.source_unit

    if not request.user.has_perm("unit.check", obj) or not request.user.has_perm(
        "source.edit", unit.translation.component
    ):
        raise PermissionDenied()

    # Mark check for ignoring
    ignore = obj.check_obj.ignore_string
    flags = Flags(unit.extra_flags)
    if ignore not in flags:
        flags.merge(ignore)
        unit.extra_flags = flags.format()
        unit.save(same_content=True)

    # response for AJAX
    return HttpResponse("ok")
Beispiel #26
0
 def test_quoted_values(self):
     flags = Flags(r"""placeholders:"bar: \"value\"":'baz \'value\''""")
     self.assertEqual(flags.get_value("placeholders"),
                      ['bar: "value"', "baz 'value'"])
     self.assertEqual(flags.format(),
                      r'''placeholders:"bar: \"value\"":"baz 'value'"''')
     flags = Flags(r'regex:"((?:@:\(|\{)[^\)\}]+(?:\)|\}))"')
     self.assertEqual(flags.format(),
                      r'regex:"((?:@:\(|\{)[^\)\}]+(?:\)|\}))"')
Beispiel #27
0
 def test_description(self):
     unit = Unit(source="string $URL$", target="string")
     unit.__dict__["all_flags"] = Flags("placeholders:$URL$")
     check = Check(unit=unit)
     self.assertHTMLEqual(
         self.check.get_description(check),
         """
         Following format strings are missing:
         <span class="hlcheck" data-value="$URL$">$URL$</span>
         """,
     )
Beispiel #28
0
 def __init__(self, id_hash=None, flags="", code="cs", source="", note=""):
     if id_hash is None:
         id_hash = random.randint(0, 65536)
     self.id_hash = id_hash
     self.flags = Flags(flags)
     self.translation = MockTranslation(code)
     self.source = source
     self.fuzzy = False
     self.translated = True
     self.state = 20
     self.note = note
Beispiel #29
0
def ignore_check_source(request, check_id):
    obj = get_object_or_404(Check, pk=int(check_id))
    unit = obj.unit.source_info
    project = unit.translation.component.project
    request.user.check_access(project)

    if (not request.user.has_perm('unit.check', project)
            or not request.user.has_perm('source.edit', unit.translation.component)):
        raise PermissionDenied()

    # Mark check for ignoring
    ignore = obj.check_obj.ignore_string
    flags = Flags(unit.extra_flags)
    if ignore not in flags:
        flags.merge(ignore)
        unit.extra_flags = flags.format()
        unit.save()

    # response for AJAX
    return HttpResponse('ok')
Beispiel #30
0
 def __init__(self, id_hash=None, flags='', code='cs', source='',
              comment=''):
     if id_hash is None:
         id_hash = random.randint(0, 65536)
     self.id_hash = id_hash
     self.flags = Flags(flags)
     self.translation = MockTranslation(code)
     self.source = source
     self.fuzzy = False
     self.translated = True
     self.comment = comment