def delete_translation(request): """Delete given translation.""" try: t = request.POST['translation'] paths = request.POST.getlist('paths[]') except MultiValueDictKeyError as e: return HttpResponseBadRequest('Bad Request: {error}'.format(error=e)) translation = get_object_or_404(Translation, pk=t) # Non-privileged users can only delete own unapproved translations if not request.user.has_perm('base.can_translate_locale', translation.locale): if translation.user == request.user: if translation.approved is True: return HttpResponseForbidden( "Forbidden: Can't delete approved translations" ) else: return HttpResponseForbidden( "Forbidden: Can't delete translations from other users" ) translation.delete() project = translation.entity.resource.project locale = translation.locale return JsonResponse({ 'stats': TranslatedResource.objects.stats(project, paths, locale), 'authors': Translation.authors(locale, project, paths).serialize(), })
def translate(request, locale, slug, part): """Translate view.""" locale = get_object_or_404(Locale, code__iexact=locale) project = get_object_or_404(Project.objects.available(), slug=slug) if locale not in project.locales.all(): raise Http404 projects = ( Project.objects.available() .prefetch_related('subpage_set') .order_by('name') ) paths = [part] if part != 'all-resources' else None authors = Translation.authors(locale, project, paths).serialize() return render(request, 'translate.html', { 'download_form': forms.DownloadFileForm(), 'upload_form': forms.UploadFileForm(), 'locale': locale, 'locales': Locale.objects.available(), 'part': part, 'project': project, 'projects': projects, 'authors': authors, })
def update_translation(request): """Update entity translation for the specified locale and user.""" try: entity = request.POST['entity'] string = request.POST['translation'] locale = request.POST['locale'] plural_form = request.POST['plural_form'] original = request.POST['original'] ignore_check = request.POST['ignore_check'] approve = json.loads(request.POST['approve']) paths = request.POST.getlist('paths[]') except MultiValueDictKeyError as e: return HttpResponseBadRequest('Bad Request: {error}'.format(error=e)) try: e = Entity.objects.get(pk=entity) except Entity.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") try: l = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") if plural_form == "-1": plural_form = None user = request.user project = e.resource.project if not request.user.is_authenticated(): if project.pk != 1: log.error("Not authenticated") return HttpResponse("error") else: user = None try: quality_checks = UserProfile.objects.get(user=user).quality_checks except UserProfile.DoesNotExist as error: quality_checks = True ignore = False if ignore_check == 'true' or not quality_checks: ignore = True now = timezone.now() can_translate = ( request.user.has_perm('base.can_translate_locale', l) and (not request.user.profile.force_suggestions or approve) ) translations = Translation.objects.filter( entity=e, locale=l, plural_form=plural_form) # Newlines are not allowed in .lang files (bug 1190754) if e.resource.format == 'lang' and '\n' in string: return HttpResponse('Newline characters are not allowed.') # Translations exist if len(translations) > 0: # Same translation exists try: t = translations.get(string=string) # If added by privileged user, approve and unfuzzy it if can_translate: # Unless there's nothing to be changed if t.user is not None and t.approved and t.approved_user \ and t.approved_date and not t.fuzzy: return JsonResponse({ 'same': True, 'message': 'Same translation already exists.', }) warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings translations.update(approved=False, approved_user=None, approved_date=None) translations.update(fuzzy=False) if t.user is None: t.user = user t.approved = True t.approved_date = timezone.now() t.fuzzy = False if t.approved_user is None: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return JsonResponse({ 'type': 'updated', 'translation': t.serialize(), 'stats': TranslatedResource.objects.stats(project, paths, l), 'authors': Translation.authors(l, project, paths).serialize(), }) # If added by non-privileged user, unfuzzy it else: if t.fuzzy: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if t.user is None: t.user = user t.approved = False t.approved_user = None t.approved_date = None t.fuzzy = False if request.user.is_authenticated(): t.save() return JsonResponse({ 'type': 'updated', 'translation': t.serialize(), 'stats': TranslatedResource.objects.stats(project, paths, l), 'authors': Translation.authors(l, project, paths).serialize(), }) return JsonResponse({ 'same': True, 'message': 'Same translation already exists.', }) # Different translation added except: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if can_translate: translations.update(approved=False, approved_user=None, approved_date=None) translations.update(fuzzy=False) t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_translate) if can_translate: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() # Return active (approved or latest) translation try: active = translations.filter(approved=True).latest("date") except Translation.DoesNotExist: active = translations.latest("date") return JsonResponse({ 'type': 'added', 'translation': active.serialize(), 'stats': TranslatedResource.objects.stats(project, paths, l), 'authors': Translation.authors(l, project, paths).serialize(), }) # No translations saved yet else: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_translate) if can_translate: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return JsonResponse({ 'type': 'saved', 'translation': t.serialize(), 'stats': TranslatedResource.objects.stats(project, paths, l), 'authors': Translation.authors(l, project, paths).serialize(), })
def entities(request): """Get entities for the specified project, locale and paths.""" try: project = request.POST['project'] locale = request.POST['locale'] paths = request.POST.getlist('paths[]') limit = int(request.POST.get('limit', 50)) except (MultiValueDictKeyError, ValueError) as err: return HttpResponseBadRequest('Bad Request: {error}'.format(error=err)) project = get_object_or_404(Project, slug=project) locale = get_object_or_404(Locale, code__iexact=locale) filter_type = request.POST.get('filter', '') search = request.POST.get('search', '') exclude_entities = request.POST.getlist('excludeEntities[]', []) # Only return entities with provided IDs (batch editing) entity_ids = request.POST.getlist('entityIds[]', []) if entity_ids: entities = ( Entity.objects.filter(pk__in=entity_ids) .prefetch_resources_translations(locale) .distinct() .order_by('order') ) return JsonResponse({ 'entities': Entity.map_entities(locale, entities), 'stats': TranslatedResource.objects.stats(project, paths, locale), 'authors': Translation.authors(locale, project, paths).serialize(), }, safe=False) entities = Entity.for_project_locale( project, locale, paths, filter_type, search, exclude_entities ) # Only return a list of entity PKs (batch editing: select all) if request.POST.get('pkOnly', None): return JsonResponse({ 'entity_pks': list(entities.values_list('pk', flat=True)), }) visible_entities = [] # In-place view: load all entities if request.POST.get('inplaceEditor', None): has_next = False entities_to_map = Entity.for_project_locale( project, locale, paths, None, None, exclude_entities ) visible_entities = entities.values_list('pk', flat=True) # Out-of-context view: paginate entities else: paginator = Paginator(entities, limit) try: entities_page = paginator.page(1) except EmptyPage: return JsonResponse({ 'has_next': False, 'stats': {}, 'authors': [] }) has_next = entities_page.has_next() entities_to_map = entities_page.object_list # If requested entity not on the first page entity = request.POST.get('entity', None) if entity: try: entity_pk = int(entity) except ValueError as err: return HttpResponseBadRequest('Bad Request: {error}'.format(error=err)) # TODO: entities_to_map.values_list() doesn't return entities from selected page if entity_pk not in [e.pk for e in entities_to_map]: if entity_pk in entities.values_list('pk', flat=True): entities_to_map = list(entities_to_map) + list(entities.filter(pk=entity_pk)) return JsonResponse({ 'entities': Entity.map_entities(locale, entities_to_map, visible_entities), 'has_next': has_next, 'stats': TranslatedResource.objects.stats(project, paths, locale), 'authors': Translation.authors(locale, project, paths).serialize(), }, safe=False)