def update_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('vcs.update', obj): raise PermissionDenied() return perform_update(request, obj)
def push_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('vcs.push', obj): raise PermissionDenied() return perform_push(request, obj)
def move_component(request, project, component): obj = get_component(request, project, component) return perform_rename( ComponentMoveForm, request, obj, 'project.edit', component=obj, target=obj.project.slug, action=Change.ACTION_MOVE_COMPONENT )
def component_progress_terminate(request, project, component): obj = get_component(request, project, component) if obj.in_progress and request.user.has_perm('component.edit', obj): obj.background_task.revoke(terminate=True) return redirect(obj)
def agreement_confirm(request, project, component): component = get_component(request, project, component) has_agreed = ContributorAgreement.objects.has_agreed( request.user, component ) if request.method == 'POST': form = ContributorAgreementForm(request.POST) if form.is_valid() and not has_agreed: ContributorAgreement.objects.create( user=request.user, component=component ) return redirect_next( request.GET.get('next'), component.get_absolute_url(), ) else: form = ContributorAgreementForm( initial={ 'next': request.GET.get('next'), 'confirm': has_agreed, } ) return render( request, 'contributor-agreement.html', { 'form': form, 'object': component, 'has_agreed': has_agreed, } )
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!') ) else: form = ComponentSettingsForm(request, instance=obj) return render( request, 'component-settings.html', { 'project': obj.project, 'object': obj, 'form': form, } )
def cleanup_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('vcs.reset', obj): raise PermissionDenied() return perform_cleanup(request, obj)
def matrix(request, project, component): """Matrix view of all strings""" obj = get_component(request, project, component) show = False languages = None language_codes = None if 'lang' in request.GET: form = MatrixLanguageForm(obj, request.GET) show = form.is_valid() else: form = MatrixLanguageForm(obj) if show: languages = Language.objects.filter( code__in=form.cleaned_data['lang'] ) language_codes = ','.join(languages.values_list('code', flat=True)) return render( request, 'matrix.html', { 'object': obj, 'project': obj.project, 'languages': languages, 'language_codes': language_codes, 'languages_form': form, } )
def mute_component(request, project, component): obj = get_component(request, project, component) mute_real(request.user, scope=SCOPE_COMPONENT, component=obj, project=None) return redirect( '{}?notify_component={}#notifications'.format( reverse('profile'), obj.pk ) )
def component_progress_js(request, project, component): obj = get_component(request, project, component) progress, log = obj.get_progress() return JsonResponse({ 'in_progress': obj.in_progress(), 'progress': progress, 'log': '\n'.join(log) })
def get_source(request, project, component): """ Returns first translation in component (this assumes all have same source strings). """ obj = get_component(request, project, component) try: return obj, obj.translation_set.all()[0] except (Translation.DoesNotExist, IndexError): raise Http404('No translation exists in this component.')
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, } )
def unlock_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('component.lock', obj): raise PermissionDenied() obj.do_lock(request.user, False) messages.success( request, _('Component is now open for translation updates.') ) return redirect_param(obj, '#repository')
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: translation = obj.add_new_language(language, request) if translation: kwargs['translation'] = translation if len(langs) == 1: obj = translation 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}, )
def render_widget(request, project, widget='287x66', color=None, lang=None, component=None, extension='png'): # We intentionally skip ACL here to allow widget sharing if component is None: obj = get_project(request, project, skip_acl=True) else: obj = get_component(request, project, component, skip_acl=True) # Handle language parameter if lang is not None: if 'native' not in request.GET: try_set_language(lang) lang = Language.objects.try_get(code=lang) else: try_set_language('en') # Get widget class try: widget_class = WIDGETS[widget] except KeyError: raise Http404() # Construct object widget_obj = widget_class(obj, color, lang) # Redirect widget if hasattr(widget_obj, 'redirect'): return redirect(widget_obj.redirect(), permanent=True) # Invalid extension if extension != widget_obj.extension or color != widget_obj.color: kwargs = { 'project': project, 'widget': widget, 'color': widget_obj.color, 'extension': widget_obj.extension, } if lang: kwargs['lang'] = lang.code return redirect('widget-image', permanent=True, **kwargs) return redirect('widget-image', permanent=True, **kwargs) # Render widget widget_obj.render() return HttpResponse( content_type=widget_obj.content_type, content=widget_obj.get_content() )
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.user) 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: translation = obj.add_new_language(language, request) if translation: kwargs["translation"] = translation if len(langs) == 1: obj = translation 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}, )
def dismiss_alert(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm("component.edit", obj): raise Http404() try: alert = obj.alert_set.get(name=request.POST["dismiss"]) if alert.obj.dismissable: alert.dismissed = True alert.save(update_fields=["dismissed"]) except ObjectDoesNotExist: pass return redirect_param(obj, "#alerts")
def component_progress(request, project, component): obj = get_component(request, project, component) return_url = 'component' if 'info' in request.get else 'guide' if not obj.in_progress(): return redirect(return_url, **obj.get_reverse_url_kwargs()) progress, log = obj.get_progress() return render( request, 'component-progress.html', { 'object': obj, 'progress': progress, 'log': '\n'.join(log), 'return_url': return_url, })
def remove_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm("component.edit", obj): raise PermissionDenied() form = ComponentDeleteForm(obj, request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, "#delete") component_removal.delay(obj.pk, request.user.pk) messages.success(request, _("Translation component was scheduled for removal.")) return redirect(obj.project)
def render_widget(request, project, widget='287x66', color=None, lang=None, component=None, extension='png'): # We intentionally skip ACL here to allow widget sharing if component is None: obj = get_project(request, project, skip_acl=True) else: obj = get_component(request, project, component, skip_acl=True) # Handle language parameter if lang is not None: lang = Language.objects.fuzzy_get(code=lang, strict=True) if lang is None: raise Http404() if 'native' not in request.GET: try_set_language(lang.code) else: try_set_language('en') # Get widget class try: widget_class = WIDGETS[widget] except KeyError: raise Http404() # Construct object widget_obj = widget_class(obj, color, lang) # Redirect widget if hasattr(widget_obj, 'redirect'): return redirect(widget_obj.redirect(), permanent=True) # Invalid extension if extension != widget_obj.extension or color != widget_obj.color: kwargs = { 'project': project, 'widget': widget, 'color': widget_obj.color, 'extension': widget_obj.extension, } if lang: kwargs['lang'] = lang.code return redirect('widget-image', permanent=True, **kwargs) return redirect('widget-image', permanent=True, **kwargs) # Render widget response = HttpResponse(content_type=widget_obj.content_type) widget_obj.render(response) return response
def git_export(request, project, component, path): """Git HTTP server view. Wrapper around git-http-backend to provide Git repositories export over HTTP. Performs permission checks and hands over execution to the wrapper. """ # Probably browser access if not path: return redirect("component", project=project, component=component, permanent=False) # Strip possible double path separators path = path.lstrip("/\\") # HTTP authentication auth = request.META.get("HTTP_AUTHORIZATION", b"") # Reject non pull access early if request.GET.get("service", "") not in ("", "git-upload-pack"): raise PermissionDenied("Only pull is supported") if auth and not authenticate(request, auth): return response_authenticate() # Permissions try: obj = get_component(request, project, component) except Http404: if not request.user.is_authenticated: return response_authenticate() raise if not request.user.has_perm("vcs.access", obj): if not request.user.is_authenticated: return response_authenticate() raise PermissionDenied("No VCS permissions") if obj.vcs not in SUPPORTED_VCS: raise Http404("Not a git repository") if obj.is_repo_link: kwargs = obj.linked_component.get_reverse_url_kwargs() kwargs["path"] = path return redirect( "{}?{}".format(reverse("git-export", kwargs=kwargs), request.META["QUERY_STRING"]), permanent=True, ) return run_git_http(request, obj, path)
def show_component(request, project, component): obj = get_component(request, project, component) user = request.user last_changes = Change.objects.prefetch().order().filter(component=obj)[:10] return render( request, 'component.html', { 'allow_index': True, 'object': obj, 'hide_alerts': True, 'project': obj.project, 'translations': sort_objects( prefetch_stats(obj.translation_set.prefetch()) ), 'reports_form': ReportsForm(), 'last_changes': last_changes, 'last_changes_url': urlencode( {'component': obj.slug, 'project': obj.project.slug} ), 'language_count': Language.objects.filter( translation__component=obj ).distinct().count(), 'replace_form': optional_form(ReplaceForm, user, 'unit.edit', obj), 'bulk_state_form': optional_form( BulkStateForm, user, 'translation.auto', obj, user=user, obj=obj ), 'whiteboard_form': optional_form( WhiteboardForm, user, 'component.edit', obj ), 'delete_form': optional_form( DeleteForm, user, 'component.edit', obj, obj=obj ), 'rename_form': optional_form( ComponentRenameForm, user, 'component.edit', obj, request=request, instance=obj ), 'move_form': optional_form( ComponentMoveForm, user, 'component.edit', obj, request=request, instance=obj ), 'search_form': SearchForm(request.user), 'alerts': obj.alert_set.order_by('name'), } )
def whiteboard_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('component.edit', obj): raise PermissionDenied() form = WhiteboardForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#whiteboard') WhiteboardMessage.objects.create(project=obj.project, component=obj, **form.cleaned_data) return redirect(obj)
def component_progress(request, project, component): obj = get_component(request, project, component) if not obj.in_progress(): return redirect(obj) progress, log = obj.get_progress() return render( request, 'component-progress.html', { 'object': obj, 'progress': progress, 'log': '\n'.join(log), } )
def announcement_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm("component.edit", obj): raise PermissionDenied() form = AnnouncementForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, "#announcement") Announcement.objects.create( user=request.user, project=obj.project, component=obj, **form.cleaned_data ) return redirect(obj)
def show_component(request, project, component): obj = get_component(request, project, component) user = request.user last_changes = Change.objects.prefetch().filter(component=obj)[:10] return render( request, 'component.html', { 'allow_index': True, 'object': obj, 'project': obj.project, 'translations': sort_objects( prefetch_stats(obj.translation_set.all()) ), 'show_language': 1, 'reports_form': ReportsForm(), 'last_changes': last_changes, 'last_changes_url': urlencode( {'component': obj.slug, 'project': obj.project.slug} ), 'language_count': Language.objects.filter( translation__component=obj ).distinct().count(), 'replace_form': optional_form(ReplaceForm, user, 'unit.edit', obj), 'bulk_state_form': optional_form( BulkStateForm, user, 'translation.auto', obj, user=user, obj=obj ), 'whiteboard_form': optional_form( WhiteboardForm, user, 'component.edit', obj ), 'delete_form': optional_form( DeleteForm, user, 'component.edit', obj, obj=obj ), 'rename_form': optional_form( ComponentRenameForm, user, 'component.edit', obj, request=request, instance=obj ), 'move_form': optional_form( ComponentMoveForm, user, 'component.edit', obj, request=request, instance=obj ), 'search_form': SearchForm(), } )
def show_component(request, project, component): obj = get_component(request, project, component) last_changes = Change.objects.prefetch().filter(component=obj)[:10] # Is user allowed to do automatic translation? if request.user.has_perm('translation.auto', obj): mass_state_form = MassStateForm(request.user, obj) else: mass_state_form = None if request.user.has_perm('unit.edit', obj): replace_form = ReplaceForm() else: replace_form = None return render( request, 'component.html', { 'allow_index': True, 'object': obj, 'project': obj.project, 'translations': sort_objects(prefetch_stats(obj.translation_set.all())), 'show_language': 1, 'reports_form': ReportsForm(), 'last_changes': last_changes, 'last_changes_url': urlencode({ 'component': obj.slug, 'project': obj.project.slug }), 'language_count': Language.objects.filter( translation__component=obj).distinct().count(), 'replace_form': replace_form, 'mass_state_form': mass_state_form, 'search_form': SearchForm(), })
def git_export(request, project, component, path): """Git HTTP server view. Wrapper around git-http-backend to provide Git repositories export over HTTP. Performs permission checks and hands over execution to the wrapper. """ # Probably browser access if not path: return redirect( 'component', project=project, component=component, permanent=False ) # Strip possible double path separators path = path.lstrip('/\\') # HTTP authentication auth = request.META.get('HTTP_AUTHORIZATION', b'') # Reject non pull access early if request.GET.get('service', '') not in ('', 'git-upload-pack'): raise PermissionDenied('Only pull is supported') if auth and not authenticate(request, auth): return response_authenticate() # Permissions try: obj = get_component(request, project, component) except Http404: if not request.user.is_authenticated: return response_authenticate() raise if not request.user.has_perm('vcs.access', obj): raise PermissionDenied('No VCS permissions') if obj.vcs not in SUPPORTED_VCS: raise Http404('Not a git repository') if obj.is_repo_link: kwargs = obj.linked_component.get_reverse_url_kwargs() kwargs['path'] = path return redirect( '{}?{}'.format( reverse('git-export', kwargs=kwargs), request.META['QUERY_STRING'] ), permanent=True, ) return run_git_http(request, obj, path)
def whiteboard_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('component.edit', obj): raise PermissionDenied() form = WhiteboardForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#whiteboard') WhiteboardMessage.objects.create( project=obj.project, component=obj, **form.cleaned_data ) return redirect(obj)
def component_progress(request, project, component): obj = get_component(request, project, component) return_url = "component" if "info" in request.GET else "guide" if not obj.in_progress(): return redirect(return_url, **obj.get_reverse_url_kwargs()) progress, log = obj.get_progress() return render( request, "component-progress.html", { "object": obj, "progress": progress, "log": "\n".join(log), "return_url": return_url, }, )
def get_detail(request, project, component, checksum): """Return source translation detail in all languages.""" component = get_component(request, project, component) try: units = Unit.objects.filter( id_hash=checksum_to_hash(checksum), translation__component=component ).order_by(*Unit.ordering) except ValueError: raise Http404('Non existing unit!') try: source = units[0].source_info except IndexError: raise Http404('Non existing unit!') check_flags = [ (CHECKS[x].ignore_string, CHECKS[x].name) for x in CHECKS ] extra_flags = [(x, EXTRA_FLAGS[x]) for x in EXTRA_FLAGS] return render( request, 'js/detail.html', { 'units': units, 'source': source, 'project': component.project, 'next': request.GET.get('next', ''), 'priority_form': PriorityForm( initial={'priority': source.priority} ), 'context_form': ContextForm( initial={'context': source.context} ), 'check_flags_form': CheckFlagsForm( initial={'flags': source.check_flags} ), 'screenshot_form': ScreenshotForm(), 'extra_flags': extra_flags, 'check_flags': check_flags, } )
def get_detail(request, project, component, checksum): """Return source translation detail in all languages.""" component = get_component(request, project, component) try: units = Unit.objects.filter( id_hash=checksum_to_hash(checksum), translation__component=component ) except ValueError: raise Http404('Non existing unit!') try: source = units[0].source_info except IndexError: raise Http404('Non existing unit!') check_flags = [ (CHECKS[x].ignore_string, CHECKS[x].name) for x in CHECKS ] extra_flags = [(x, EXTRA_FLAGS[x]) for x in EXTRA_FLAGS] return render( request, 'js/detail.html', { 'units': units, 'source': source, 'project': component.project, 'next': request.GET.get('next', ''), 'priority_form': PriorityForm( initial={'priority': source.priority} ), 'context_form': ContextForm( initial={'context': source.context} ), 'check_flags_form': CheckFlagsForm( initial={'flags': source.check_flags} ), 'screenshot_form': ScreenshotForm(), 'extra_flags': extra_flags, 'check_flags': check_flags, } )
def remove_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('component.edit', obj): raise PermissionDenied() form = DeleteForm(obj, request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#delete') obj.delete() messages.success(request, _('Translation component has been removed.')) Change.objects.create(project=obj.project, action=Change.ACTION_REMOVE_COMPONENT, target=obj.slug, user=request.user, author=request.user) return redirect(obj.project)
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 }, )
def new_language(request, project, component): obj = get_component(request, project, component) form_class = get_new_language_form(request, obj) if request.method == 'POST': form = form_class(obj, request.POST) if form.is_valid(): langs = form.cleaned_data['lang'] for language in Language.objects.filter(code__in=langs): if obj.new_lang == 'contact': notify_new_language(obj, language, request.user) messages.success( request, _( "A request for a new translation has been " "sent to the project's maintainers." ) ) elif obj.new_lang == 'add': obj.add_new_language(language, request) return redirect(obj) else: 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, } )
def git_export(request, project, component, path): """Git HTTP server view. Wrapper around git-http-backend to provide Git repositories export over HTTP. Performs permission checks and hands over execution to the wrapper. """ # Probably browser access if not path: return redirect( 'component', project=project, component=component, permanent=False ) # Strip possible double path separators path = path.lstrip('/\\') # HTTP authentication auth = request.META.get('HTTP_AUTHORIZATION', b'') # Reject non pull access early if request.GET.get('service', '') not in ('', 'git-upload-pack'): raise PermissionDenied('Only pull is supported') if auth and not authenticate(request, auth): return response_authenticate() # Permissions try: obj = get_component(request, project, component) except Http404: if not request.user.is_authenticated: return response_authenticate() raise if not request.user.has_perm('vcs.access', obj): raise PermissionDenied('No VCS permissions') if obj.vcs not in SUPPORTED_VCS: raise Http404('Not a git repository') return run_git_http(request, obj, path)
def matrix_load(request, project, component): """Backend for matrix view of all strings""" obj = get_component(request, project, component) try: offset = int(request.GET.get('offset', '')) except ValueError: return HttpResponseServerError('Missing offset') language_codes = request.GET.get('lang') if not language_codes or offset is None: return HttpResponseServerError('Missing lang') # Can not use filter to keep ordering translations = [ get_object_or_404(obj.translation_set, language__code=lang) for lang in language_codes.split(',') ] data = [] for unit in translations[0].unit_set.all()[offset:offset + 20]: units = [] for translation in translations: try: units.append(translation.unit_set.get(id_hash=unit.id_hash)) except Unit.DoesNotExist: units.append(None) data.append((unit, units)) return render( request, 'matrix-table.html', { 'object': obj, 'data': data, 'last': translations[0].unit_set.count() <= offset + 20 } )
def matrix_load(request, project, component): """Backend for matrix view of all strings.""" obj = get_component(request, project, component) try: offset = int(request.GET.get("offset", "")) except ValueError: return HttpResponseServerError("Missing offset") language_codes = request.GET.get("lang") if not language_codes or offset is None: return HttpResponseServerError("Missing lang") # Can not use filter to keep ordering translations = [ get_object_or_404(obj.translation_set, language__code=lang) for lang in language_codes.split(",") ] data = [] for unit in translations[0].unit_set.all()[offset:offset + 20]: units = [] for translation in translations: try: units.append(translation.unit_set.get(id_hash=unit.id_hash)) except Unit.DoesNotExist: units.append(None) data.append((unit, units)) return render( request, "matrix-table.html", { "object": obj, "data": data, "last": translations[0].unit_set.count() <= offset + 20, }, )
def remove_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('component.edit', obj): raise PermissionDenied() form = DeleteForm(obj, request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#delete') obj.delete() messages.success(request, _('Translation component has been removed.')) Change.objects.create( project=obj.project, action=Change.ACTION_REMOVE_COMPONENT, target=obj.slug, user=request.user, author=request.user ) return redirect(obj.project)
def show_check_component(request, name, project, component): """Show checks failing in a component.""" component = get_component(request, project, component) try: check = CHECKS[name] except KeyError: raise Http404("No check matches the given query.") kwargs = {} if request.GET.get("lang"): kwargs["language__code"] = request.GET["lang"] translations = ( Translation.objects.filter( component=component, unit__check__check=name, **kwargs ) .annotate( check_count=Count("unit__check"), dismissed_check_count=conditional_sum(1, unit__check__dismissed=True), active_check_count=conditional_sum(1, unit__check__dismissed=False), translated_check_count=conditional_sum( 1, unit__check__dismissed=False, unit__state__gte=STATE_TRANSLATED ), ) .order_by("language__code") .select_related("language") ) return render( request, "check_component.html", { "translations": translations, "title": "{0}/{1}".format(force_str(component), check.name), "check": check, "component": component, }, )
def parse_url(request, project, component=None, lang=None): context = {} if component is None: obj = get_project(request, project) unit_set = Unit.objects.filter(translation__component__project=obj) context["project"] = obj elif lang is None: obj = get_component(request, project, component) unit_set = Unit.objects.filter(translation__component=obj) context["component"] = obj context["project"] = obj.project else: obj = get_translation(request, project, component, lang) unit_set = obj.unit_set.all() context["translation"] = obj context["component"] = obj.component context["project"] = obj.component.project if not request.user.has_perm("unit.edit", obj): raise PermissionDenied() return obj, unit_set, context
def export_stats(request, project, component): """Export stats in JSON format.""" subprj = get_component(request, project, component) translations = subprj.translation_set.order_by("language_code") return export_response( request, f"stats-{subprj.project.slug}-{subprj.slug}.csv", ( "name", "code", "total", "translated", "translated_percent", "translated_words_percent", "total_words", "translated_words", "total_chars", "translated_chars", "translated_chars_percent", "failing", "failing_percent", "fuzzy", "fuzzy_percent", "url_translate", "url", "translate_url", "last_change", "last_author", "recent_changes", "readonly", "readonly_percent", "approved", "approved_percent", "suggestions", "comments", ), StatisticsSerializer(translations, many=True).data, )
def parse_url(request, project, component=None, lang=None): context = {} if component is None: obj = get_project(request, project) unit_set = Unit.objects.filter(translation__component__project=obj) context['project'] = obj elif lang is None: obj = get_component(request, project, component) unit_set = Unit.objects.filter(translation__component=obj) context['component'] = obj context['project'] = obj.project else: obj = get_translation(request, project, component, lang) unit_set = obj.unit_set context['translation'] = obj context['component'] = obj.component context['project'] = obj.component.project if not request.user.has_perm('unit.edit', obj): raise PermissionDenied() return obj, unit_set, context
def git_export(request, project, component, path): """Git HTTP server view. Wrapper around git-http-backend to provide Git repositories export over HTTP. Performs permission checks and hands over execution to the wrapper. """ # Probably browser access if not path: return redirect( 'component', project=project, component=component, permanent=False ) # Strip possible double path separators path = path.lstrip('/\\') # HTTP authentication auth = request.META.get('HTTP_AUTHORIZATION', b'') # Reject non pull access early if request.GET.get('service', '') not in ('', 'git-upload-pack'): raise PermissionDenied('Only pull is supported') if auth and not authenticate(request, auth): return response_authenticate() # Permissions try: obj = get_component(request, project, component) except Http404: if not request.user.is_authenticated: return response_authenticate() raise if not request.user.has_perm('vcs.access', obj): raise PermissionDenied('No VCS permissions') return run_git_http(request, obj, path)
def git_status_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('meta:vcs.status', obj): raise PermissionDenied() target = obj if target.is_repo_link: target = target.linked_component return render( request, 'js/git-status.html', { 'object': obj, 'project': obj.project, 'changes': Change.objects.filter( action__in=Change.ACTIONS_REPOSITORY, component=target, )[:10], 'statuses': [(None, obj.repository.status)], } )
def git_status_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm('meta:vcs.status', obj): raise PermissionDenied() target = obj if target.is_repo_link: target = target.linked_component return render( request, 'js/git-status.html', { 'object': obj, 'project': obj.project, 'changes': Change.objects.filter( action__in=Change.ACTIONS_REPOSITORY, component=target, ).order_by(*Change.ordering)[:10], 'statuses': [(None, obj.repository.status)], } )
def watch(request, project, component=None): user = request.user if component: redirect_obj = component_obj = get_component(request, project, component) obj = component_obj.project # Mute project level subscriptions mute_real(user, scope=SCOPE_PROJECT, component=None, project=obj) # Manually enable component level subscriptions for default_subscription in user.subscription_set.filter(scope=SCOPE_DEFAULT): subscription, created = user.subscription_set.get_or_create( notification=default_subscription.notification, scope=SCOPE_COMPONENT, component=component_obj, project=None, defaults={"frequency": default_subscription.frequency}, ) if not created and subscription.frequency != default_subscription.frequency: subscription.frequency = default_subscription.frequency subscription.save(update_fields=["frequency"]) else: redirect_obj = obj = get_project(request, project) user.profile.watched.add(obj) return redirect(redirect_obj)
def git_status_component(request, project, component): obj = get_component(request, project, component) if not request.user.has_perm("meta:vcs.status", obj): raise PermissionDenied() target = obj if target.is_repo_link: target = target.linked_component return render( request, "js/git-status.html", { "object": obj, "project": obj.project, "changes": Change.objects.filter( action__in=Change.ACTIONS_REPOSITORY, component=target ).order()[:10], "statuses": [(None, obj.repository.status)], "component": obj, }, )
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!") ) else: form = ComponentSettingsForm(request, instance=obj) return render( request, "component-settings.html", {"project": obj.project, "object": obj, "form": form}, )
def show_component(request, project, component): obj = get_component(request, project, component) user = request.user last_changes = Change.objects.prefetch().filter(component=obj)[:10] return render( request, 'component.html', { 'allow_index': True, 'object': obj, 'project': obj.project, 'translations': sort_objects( prefetch_stats(obj.translation_set.all()) ), 'show_language': 1, 'reports_form': ReportsForm(), 'last_changes': last_changes, 'last_changes_url': urlencode( {'component': obj.slug, 'project': obj.project.slug} ), 'language_count': Language.objects.filter( translation__component=obj ).distinct().count(), 'replace_form': optional_form(ReplaceForm, user, 'unit.edit', obj), 'mass_state_form': optional_form( MassStateForm, user, 'translation.auto', obj, user=user, obj=obj ), 'delete_form': optional_form( DeleteForm, user, 'component.edit', obj, obj=obj ), 'search_form': SearchForm(), } )
def export_stats(request, project, component): """Export stats in JSON format.""" subprj = get_component(request, project, component) data = [trans.get_stats() for trans in subprj.translation_set.all()] return export_response( request, 'stats-{0}-{1}.csv'.format(subprj.project.slug, subprj.slug), ( 'name', 'code', 'total', 'translated', 'translated_percent', 'total_words', 'translated_words', 'failing', 'failing_percent', 'fuzzy', 'fuzzy_percent', 'url_translate', 'url', 'last_change', 'last_author', ), data)
def rename_component(request, project, component): obj = get_component(request, project, component) return perform_rename( ComponentRenameForm, request, obj, 'component.edit', component=obj, target=obj.slug, action=Change.ACTION_RENAME_COMPONENT )
def show_check_component(request, name, project, component): """Show checks failing in a component.""" subprj = get_component(request, project, component) try: check = CHECKS[name] except KeyError: raise Http404('No check matches the given query.') ignore = ('ignored' in request.GET) url_params = {} allchecks = acl_checks(request.user).filter( check=name, project=subprj.project, ignore=ignore, ) if ignore: url_params['ignored'] = 'true' if check.source: url_params['type'] = check.url_id return redirect_param( 'review_source', encode_optional(url_params), project=subprj.project.slug, component=subprj.slug, ) if request.GET.get('language') and '/' not in request.GET['language']: url_params['type'] = check.url_id return redirect_param( 'translate', encode_optional(url_params), project=subprj.project.slug, component=subprj.slug, lang=request.GET['language'], ) units = Unit.objects.none() if check.target: langs = allchecks.values_list( 'language', flat=True ).distinct() for lang in langs: checks = allchecks.filter( language=lang, ).values_list('content_hash', flat=True) res = Unit.objects.filter( translation__component=subprj, content_hash__in=checks, translation__language=lang, ).values( 'translation__language__code' ).annotate(count=Count('id')) units |= res counts = {} for unit in units: key = unit['translation__language__code'] if key in counts: counts[key] += unit['count'] else: counts[key] = unit['count'] units = [ { 'translation__language__code': item, 'count': counts[item] } for item in counts ] return render( request, 'check_component.html', { 'checks': units, 'title': '{0}/{1}'.format(force_text(subprj), check.name), 'check': check, 'component': subprj, 'url_params': encode_optional(url_params), } )
def get_object(self, request, project, component): return get_component(request, project, component)
def get_credits(request, project, component): """View for credits""" obj = get_component(request, project, component) if not request.user.has_perm('reports.view', obj): raise PermissionDenied() form = ReportsForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#reports') data = generate_credits( obj, form.cleaned_data['start_date'], form.cleaned_data['end_date'], ) if form.cleaned_data['style'] == 'json': return JsonResponse(data=data, safe=False) if form.cleaned_data['style'] == 'html': start = '<table>' row_start = '<tr>' language_format = '<th>{0}</th>' translator_start = '<td><ul>' translator_format = '<li><a href="mailto:{0}">{1}</a></li>' translator_end = '</ul></td>' row_end = '</tr>' mime = 'text/html' end = '</table>' else: start = '' row_start = '' language_format = '* {0}\n' translator_start = '' translator_format = ' * {1} <{0}>' translator_end = '' row_end = '' mime = 'text/plain' end = '' result = [] result.append(start) for language in data: name, translators = language.popitem() result.append(row_start) result.append(language_format.format(name)) result.append( ''.join(( translator_start, '\n'.join( [translator_format.format(*t) for t in translators] ), translator_end, )) ) result.append(row_end) result.append(end) return HttpResponse( '\n'.join(result), content_type='{0}; charset=utf-8'.format(mime), )
def get_counts(request, project, component): """View for work counts""" obj = get_component(request, project, component) if not request.user.has_perm('reports.view', obj): raise PermissionDenied() form = ReportsForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#reports') data = generate_counts( obj, form.cleaned_data['start_date'], form.cleaned_data['end_date'], ) if form.cleaned_data['style'] == 'json': return JsonResponse(data=data, safe=False) headers = ( 'Name', 'Email', 'Count total', 'Source words total', 'Source chars total', 'Target words total', 'Target chars total', 'Count new', 'Source words new', 'Source chars new', 'Target words new', 'Target chars new', 'Count approved', 'Source words approved', 'Source chars approved', 'Target words approved', 'Target chars approved', 'Count edited', 'Source words edited', 'Source chars edited', 'Target words edited', 'Target chars edited', ) if form.cleaned_data['style'] == 'html': start = HTML_HEADING.format( ''.join(['<th>{0}</th>'.format(h) for h in headers]) ) row_start = '<tr>' cell_name = cell_count = '<td>{0}</td>\n' row_end = '</tr>' mime = 'text/html' end = '</table>' else: start = '{0}\n{1} {2}\n{0}'.format( RST_HEADING, ' '.join(['{0:40}'.format(h) for h in headers[:2]]), ' '.join(['{0:24}'.format(h) for h in headers[2:]]), ) row_start = '' cell_name = '{0:40} ' cell_count = '{0:24} ' row_end = '' mime = 'text/plain' end = RST_HEADING result = [] result.append(start) for item in data: if row_start: result.append(row_start) result.append( ''.join(( cell_name.format(item['name']), cell_name.format(item['email']), cell_count.format(item['count']), cell_count.format(item['words']), cell_count.format(item['chars']), cell_count.format(item['t_words']), cell_count.format(item['t_chars']), cell_count.format(item['count_new']), cell_count.format(item['words_new']), cell_count.format(item['chars_new']), cell_count.format(item['t_words_new']), cell_count.format(item['t_chars_new']), cell_count.format(item['count_approve']), cell_count.format(item['words_approve']), cell_count.format(item['chars_approve']), cell_count.format(item['t_words_approve']), cell_count.format(item['t_chars_approve']), cell_count.format(item['count_edit']), cell_count.format(item['words_edit']), cell_count.format(item['chars_edit']), cell_count.format(item['t_words_edit']), cell_count.format(item['t_chars_edit']), )) ) if row_end: result.append(row_end) result.append(end) return HttpResponse( '\n'.join(result), content_type='{0}; charset=utf-8'.format(mime), )
def mute_component(request, project, component): obj = get_component(request, project, component) mute_real(request.user, scope=SCOPE_COMPONENT, component=obj, project=None) return redirect('{}?notify_component={}#notifications'.format( reverse('profile'), obj.pk))
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 = SiteSearchForm(request.GET) context = { 'search_form': search_form, } search_kwargs = {} if component: obj = get_component(request, project, component) context['component'] = obj context['project'] = obj.project context['back_url'] = obj.get_absolute_url() search_kwargs = {'component': obj} elif project: obj = get_project(request, project) context['project'] = obj context['back_url'] = obj.get_absolute_url() search_kwargs = {'project': obj} else: obj = None context['back_url'] = None if lang: s_language = get_object_or_404(Language, code=lang) context['language'] = s_language search_kwargs = {'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(): # Filter results by ACL if component: units = Unit.objects.filter(translation__component=obj) elif project: units = Unit.objects.filter(translation__component__project=obj) else: allowed_projects = request.user.allowed_projects units = Unit.objects.filter( translation__component__project__in=allowed_projects ) units = units.search( search_form.cleaned_data, **search_kwargs ) if lang: units = units.filter( translation__language=context['language'] ) units = get_paginator(request, units) context['show_results'] = True context['page_obj'] = units context['title'] = _('Search for %s') % ( search_form.cleaned_data['q'] ) context['query_string'] = search_form.urlencode() context['search_query'] = search_form.cleaned_data['q'] 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 )