def matrix(request, project, subproject): """Matrix view of all strings""" obj = get_subproject(request, project, subproject) 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 show_engage(request, project, lang=None): # Get project object, skipping ACL obj = get_project(request, project, skip_acl=True) # Handle language parameter if lang is not None: language = Language.objects.try_get(code=lang) else: language = None if language: try_set_language(lang) stats_obj = obj.stats.get_single_language_stats(language) else: stats_obj = obj.stats return render( request, 'engage.html', { 'allow_index': True, 'object': obj, 'project': obj, 'languages': stats_obj.languages, 'total': obj.stats.source_strings, 'percent': stats_obj.translated_percent, 'language': language, 'title': _('Get involved in {0}!').format(obj), } )
def zen(request, project, subproject, lang): ''' Generic entry point for translating, suggesting and searching. ''' translation = get_translation(request, project, subproject, lang) search_result, unitdata = get_zen_unitdata(translation, request) # Handle redirects if isinstance(search_result, HttpResponse): return search_result return render( request, 'zen.html', { 'object': translation, 'project': translation.subproject.project, 'unitdata': unitdata, 'search_query': search_result['query'], 'filter_name': search_result['name'], 'filter_count': len(search_result['ids']), 'last_section': search_result['last_section'], 'search_id': search_result['search_id'], 'offset': search_result['offset'], } )
def zen(request, project, subproject, lang): """ Generic entry point for translating, suggesting and searching. """ translation = get_translation(request, project, subproject, lang) search_result, unitdata = get_zen_unitdata(translation, request) # Handle redirects if isinstance(search_result, HttpResponse): return search_result return render( request, "zen.html", { "object": translation, "project": translation.subproject.project, "unitdata": unitdata, "search_query": search_result["query"], "filter_name": search_result["name"], "filter_count": len(search_result["ids"]), "last_section": search_result["last_section"], "search_id": search_result["search_id"], "offset": search_result["offset"], }, )
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(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', {}, )
def show_engage(request, project, lang=None): # Get project object, skipping ACL obj = get_project(request, project, skip_acl=True) # Handle language parameter if lang is not None: language = get_object_or_404(Language, code=lang) else: language = None full_stats = obj.stats if language: try_set_language(lang) stats_obj = full_stats.get_single_language_stats(language) else: stats_obj = full_stats return render( request, 'engage.html', { 'allow_index': True, 'object': obj, 'project': obj, 'full_stats': full_stats, 'languages': stats_obj.languages, 'total': obj.stats.source_strings, 'percent': stats_obj.translated_percent, 'language': language, 'project_link': mark_safe('<a href="{}">{}</a>'.format( escape(obj.get_absolute_url()), escape(obj.name) )), 'title': _('Get involved in {0}!').format(obj), } )
def zen(request, project, subproject, lang): """Generic entry point for translating, suggesting and searching.""" translation = get_translation(request, project, subproject, lang) search_result, unitdata = get_zen_unitdata(translation, request) # Handle redirects if isinstance(search_result, HttpResponse): return search_result return render( request, 'zen.html', { 'object': translation, 'project': translation.subproject.project, 'unitdata': unitdata, 'search_query': search_result['query'], 'filter_name': search_result['name'], 'filter_count': len(search_result['ids']), 'last_section': search_result['last_section'], 'search_url': search_result['url'], 'offset': search_result['offset'], 'search_form': search_result['form'].reset_offset(), 'update_lock': translation.lock_user == request.user, } )
def show_subproject(request, project, subproject): obj = get_subproject(request, project, subproject) last_changes = Change.objects.prefetch().filter( translation__subproject=obj )[:10] new_lang_form = get_new_language_form(request, obj)(obj) return render( request, 'subproject.html', { 'object': obj, 'project': obj.project, 'translations': sort_objects(obj.translation_set.enabled()), 'show_language': 1, 'reports_form': ReportsForm(), 'last_changes': last_changes, 'last_changes_url': urlencode( {'subproject': obj.slug, 'project': obj.project.slug} ), 'new_lang_form': new_lang_form, } )
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, } )
def show_project(request, project): obj = get_project(request, project) user = request.user dict_langs = Language.objects.filter( dictionary__project=obj ).annotate(Count('dictionary')) last_changes = Change.objects.prefetch().filter(project=obj)[:10] language_stats = sort_unicode( obj.stats.get_language_stats(), lambda x: force_text(x.language.name) ) # Paginate components of project. all_components = obj.component_set.select_related() components = prefetch_stats(get_paginator( request, all_components )) return render( request, 'project.html', { 'allow_index': True, 'object': obj, 'project': obj, 'dicts': dict_langs, 'last_changes': last_changes, 'last_changes_url': urlencode( {'project': obj.slug} ), 'language_stats': language_stats, 'language_count': Language.objects.filter( translation__component__project=obj ).distinct().count(), 'search_form': SearchForm(), 'whiteboard_form': optional_form( WhiteboardForm, user, 'project.edit', obj ), 'delete_form': optional_form( DeleteForm, user, 'project.edit', obj, obj=obj ), 'rename_form': optional_form( ProjectRenameForm, user, 'project.edit', obj, request=request, instance=obj ), 'replace_form': optional_form(ReplaceForm, user, 'unit.edit', obj), 'bulk_state_form': optional_form( BulkStateForm, user, 'translation.auto', obj, user=user, obj=obj ), 'components': components, 'licenses': ', '.join( sorted({x.license for x in all_components if x.license}) ), } )
def show_engage(request, project, lang=None): # Get project object, skipping ACL obj = get_project(request, project, skip_acl=True) # Handle language parameter if lang is not None: language = Language.objects.try_get(code=lang) else: language = None if language: try_set_language(lang) stats_obj = obj.stats.get_single_language_stats(language) else: stats_obj = obj.stats percent = stats_obj.translated_percent languages = obj.get_language_count() context = { 'allow_index': True, 'object': obj, 'project': obj, 'languages': languages, 'total': obj.stats.source_strings, 'percent': percent, 'url': obj.get_absolute_url(), 'lang_url': obj.get_absolute_url() + '#languages', 'language': language, 'title': _('Get involved in {0}!').format(obj), } # Render text if language is None: status_text = _( '<a href="%(url)s">Translation project for %(project)s</a> ' 'currently contains %(total)s strings for translation and is ' '<a href="%(lang_url)s">being translated into %(languages)s ' 'languages</a>. Overall, these translations are %(percent)s%% ' 'complete.' ) else: # Translators: line of text in engagement page, please use your # language name instead of English status_text = _('<a href="%(url)s">Translation project for ' '%(project)s</a> into English currently contains ' '%(total)s strings for translation and is ' '%(percent)s%% complete.') if 'English' in status_text: status_text = status_text.replace('English', language.name) context['status_text'] = mark_safe(status_text % context) return render( request, 'engage.html', context )
def data_root(request): return render( request, 'data-root.html', { 'hooks_docs': weblate.get_doc_url('api', 'hooks'), 'api_docs': weblate.get_doc_url('api'), 'rss_docs': weblate.get_doc_url('api', 'rss'), } )
def show_component_list(request, name): obj = get_object_or_404(ComponentList, slug=name) return render( request, 'component-list.html', { 'object': obj, } )
def data_project(request, project): obj = get_project(request, project) return render( request, 'data.html', { 'object': obj, 'project': obj, } )
def bad_request(request, exception=None): """Error handler for bad request.""" return render( request, '400.html', { 'title': _('Bad Request'), }, status=400 )
def not_found(request, exception=None): """Error handler showing list of available projects.""" return render( request, '404.html', { 'title': _('Page Not Found'), }, status=404 )
def denied(request, exception=None): """Error handler showing list of available projects.""" return render( request, '403.html', { 'title': _('Permission Denied'), }, status=403 )
def show_translation(request, project, subproject, lang): obj = get_translation(request, project, subproject, lang) last_changes = Change.objects.for_translation(obj)[:10] # Check locks obj.is_locked(request.user) # Get form form = get_upload_form(request.user, obj.subproject.project)() # Is user allowed to do automatic translation? if can_automatic_translation(request.user, obj.subproject.project): autoform = AutoForm(obj, request.user) else: autoform = None # Search form for everybody search_form = SearchForm() # Review form for logged in users if request.user.is_anonymous(): review_form = None else: review_form = ReviewForm( initial={ 'date': timezone.now().date() - datetime.timedelta(days=31) } ) replace_form = None if can_translate(request.user, obj): replace_form = ReplaceForm() return render( request, 'translation.html', { 'object': obj, 'project': obj.subproject.project, 'form': form, 'autoform': autoform, 'search_form': search_form, 'review_form': review_form, 'replace_form': replace_form, 'last_changes': last_changes, 'last_changes_url': urlencode(obj.get_kwargs()), 'show_only_component': True, 'other_translations': Translation.objects.prefetch().filter( subproject__project=obj.subproject.project, language=obj.language, ).exclude( pk=obj.pk ), } )
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 not_found(request): """Error handler showing list of available projects.""" return render( request, '404.html', { 'request_path': request.path, 'title': _('Page Not Found'), }, status=404 )
def denied(request): """Error handler showing list of available projects.""" return render( request, '403.html', { 'request_path': request.path, 'title': _('Permission Denied'), }, status=403 )
def about(request): """Show about page with version information.""" return render( request, 'about.html', { 'title': _('About Weblate'), 'versions': get_versions() + get_optional_versions(), 'allow_index': True, } )
def list_projects(request): """Lists all projects""" return render( request, 'projects.html', { 'projects': Project.objects.all_acl(request.user), 'title': _('Projects'), } )
def search(request): """ Performs site-wide search on units. """ search_form = SiteSearchForm(request.GET) context = { 'search_form': search_form, } if search_form.is_valid(): units = Unit.objects.search( None, search_form.cleaned_data, ).select_related( 'translation', ) # Filter results by ACL acl_projects, filtered = Project.objects.get_acl_status(request.user) if filtered: units = units.filter( translation__subproject__project__in=acl_projects ) limit = request.GET.get('limit', 50) page = request.GET.get('page', 1) paginator = Paginator(units, limit) try: units = paginator.page(page) except PageNotAnInteger: # If page is not an integer, deliver first page. units = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of # results. units = paginator.page(paginator.num_pages) 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'] else: messages.error(request, _('Invalid search query!')) return render( request, 'search.html', context )
def list_projects(request): """List all projects""" return render( request, 'projects.html', { 'allow_index': True, 'projects': prefetch_stats(request.user.allowed_projects), 'title': _('Projects'), } )
def about(request): """ Shows about page with version information. """ context = {} context['title'] = _('About Weblate') context['versions'] = get_versions() + get_optional_versions() return render( request, 'about.html', context )
def show_component_list(request, name): obj = get_object_or_404(ComponentList, slug=name) return render( request, 'component-list.html', { 'object': obj, 'components': obj.components.filter( project__in=request.user.allowed_projects ) } )
def data_project(request, project): obj = get_project(request, project) return render( request, 'data.html', { 'object': obj, 'project': obj, 'hooks_docs': weblate.get_doc_url('api', 'hooks'), 'api_docs': weblate.get_doc_url('api'), 'rss_docs': weblate.get_doc_url('api', 'rss'), } )
def review_source(request, project, component): """Listing of source strings to review.""" obj, source = get_source(request, project, component) # Grab search type and page number rqtype = request.GET.get('type', 'all') page, limit = get_page_limit(request, 50) try: id_hash = checksum_to_hash(request.GET.get('checksum', '')) except ValueError: id_hash = None ignored = 'ignored' in request.GET expand = False query_string = {'type': rqtype} if ignored: query_string['ignored'] = 'true' # Filter units: if id_hash: sources = source.unit_set.filter(id_hash=id_hash) expand = True else: sources = source.unit_set.filter_type( rqtype, source.component.project, source.language, ignored ) paginator = Paginator(sources, limit) try: sources = paginator.page(page) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. sources = paginator.page(paginator.num_pages) return render( request, 'source-review.html', { 'object': obj, 'project': obj.project, 'source': source, 'page_obj': sources, 'query_string': urlencode(query_string), 'ignored': ignored, 'expand': expand, 'title': _('Review source strings in %s') % force_text(obj), } )
def edit_dictionary(request, project, lang, pk): prj = get_project(request, project) if not request.user.has_perm('glossary.edit', prj): raise PermissionDenied() lang = get_object_or_404(Language, code=lang) word = get_object_or_404( Dictionary, project=prj, language=lang, id=pk, ) if request.method == 'POST': form = WordForm(request.POST) if form.is_valid(): word.edit( request, form.cleaned_data['source'], form.cleaned_data['target'] ) return redirect( 'show_dictionary', project=prj.slug, lang=lang.code ) else: form = WordForm( initial={'source': word.source, 'target': word.target} ) last_changes = Change.objects.last_changes(request.user).filter( dictionary=word, )[:10] return render( request, 'edit_dictionary.html', { 'title': dict_title(prj, lang), 'project': prj, 'language': lang, 'form': form, 'last_changes': last_changes, 'last_changes_url': urlencode({ 'project': prj.slug, 'lang': lang.code, 'glossary': 1 }), } )
def show_project(request, project): obj = get_project(request, project) dict_langs = Dictionary.objects.filter( project=obj ).values_list( 'language', flat=True ).distinct() dicts = [] for language in Language.objects.filter(id__in=dict_langs): dicts.append( { 'language': language, 'count': Dictionary.objects.filter( language=language, project=obj ).count(), } ) last_changes = Change.objects.prefetch().filter( Q(translation__subproject__project=obj) | Q(dictionary__project=obj) )[:10] return render( request, 'project.html', { 'object': obj, 'project': obj, 'dicts': dicts, 'last_changes': last_changes, 'last_changes_url': urlencode( {'project': obj.slug} ), 'add_user_form': UserManageForm(), } )
def show_engage(request, project, lang=None): # Get project object, skipping ACL obj = get_project(request, project, skip_acl=True) # Handle language parameter language = None if lang is not None: try_set_language(lang) language = Language.objects.try_get(code=lang) context = { 'object': obj, 'project': obj, 'languages': obj.get_language_count(), 'total': obj.get_total(), 'percent': obj.get_translated_percent(language), 'url': obj.get_absolute_url(), 'language': language, } # Render text if language is None: status_text = _( '<a href="%(url)s">Translation project for %(project)s</a> ' 'currently contains %(total)s strings for translation and is ' '<a href="%(url)s">being translated into %(languages)s languages' '</a>. Overall, these translations are %(percent)s%% complete.') else: # Translators: line of text in engagement widget, please use your # language name instead of English status_text = _('<a href="%(url)s">Translation project for ' '%(project)s</a> into English currently contains ' '%(total)s strings for translation and is ' '%(percent)s%% complete.') if 'English' in status_text: status_text = status_text.replace('English', language.name) context['status_text'] = mark_safe(status_text % context) return render(request, 'engage.html', context)
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 show_component(request, project, component): obj = get_component(request, project, component) last_changes = Change.objects.for_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 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 show_glossaries(request, project): obj = get_project(request, project) language_glossaries = LanguageGlossary(obj, request.POST, request.user) new_form = GlossaryForm(request.user, obj) if request.method == "POST" and request.user.has_perm("project.edit", obj): if "delete_glossary" in request.POST: try: glossary = language_glossaries.glossaries.get( pk=int(request.POST["delete_glossary"])) glossary.delete() return redirect("show_glossaries", project=obj.slug) except (Glossary.DoesNotExist, ValueError): messages.error(request, _("Glossary was not found.")) elif language_glossaries.post_id == -1: new_form = GlossaryForm(request.user, obj, data=request.POST) if new_form.is_valid(): new_form.instance.project = obj new_form.save() return redirect("show_glossaries", project=obj.slug) else: try: glossary = language_glossaries.get_edited_glossary() form = language_glossaries.forms[glossary.id] if form.is_valid(): form.save() return redirect("show_glossaries", project=obj.slug) except Glossary.DoesNotExist: messages.error(request, _("Glossary was not found.")) return render( request, "glossaries.html", { "title": _("Glossaries"), "object": obj, "language_glossaries": language_glossaries.get_glossaries(), "project": obj, "new_form": new_form, }, )
def show_engage(request, project, lang=None): # Get project object, skipping ACL obj = get_project(request, project, skip_acl=True) # Handle language parameter if lang is not None: language = get_object_or_404(Language, code=lang) else: language = None full_stats = obj.stats if language: try_set_language(lang) stats_obj = full_stats.get_single_language_stats(language) else: stats_obj = full_stats return render( request, 'engage.html', { 'allow_index': True, 'object': obj, 'project': obj, 'full_stats': full_stats, 'languages': stats_obj.languages, 'total': obj.stats.source_strings, 'percent': stats_obj.translated_percent, 'language': language, 'project_link': mark_safe('<a href="{}">{}</a>'.format( escape(obj.get_absolute_url()), escape(obj.name))), 'title': _('Get involved in {0}!').format(obj), })
def manage_access(request, project): """User management view.""" obj = get_project(request, project) if not request.user.has_perm('project.permissions', obj): raise PermissionDenied() if request.user.has_perm('billing:project.permissions', obj): access_form = ProjectAccessForm(instance=obj) else: access_form = DisabledProjectAccessForm(instance=obj) return render( request, 'manage-access.html', { 'object': obj, 'project': obj, 'groups': Group.objects.for_project(obj), 'all_users': User.objects.for_project(obj), 'add_user_form': UserManageForm(), 'invite_user_form': InviteUserForm(), 'access_form': access_form, })
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 zen(request, project, component, lang): """Generic entry point for translating, suggesting and searching.""" translation = get_translation(request, project, component, lang) search_result, unitdata = get_zen_unitdata(translation, request) # Handle redirects if isinstance(search_result, HttpResponse): return search_result return render( request, 'zen.html', { 'object': translation, 'project': translation.component.project, 'unitdata': unitdata, 'search_query': search_result['query'], 'filter_name': search_result['name'], 'filter_count': len(search_result['ids']), 'last_section': search_result['last_section'], 'search_url': search_result['url'], 'offset': search_result['offset'], 'search_form': search_result['form'].reset_offset(), })
def matrix_load(request, project, subproject): """Backend for matrix view of all strings""" obj = get_subproject(request, project, subproject) 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 stats(request): """View with Various stats about Weblate.""" context = {} context['title'] = _('Weblate statistics') totals = Profile.objects.aggregate( Sum('translated'), Sum('suggested'), Count('id') ) total_strings = [] total_words = [] for project in prefetch_stats(Project.objects.all()): total_strings.append(project.stats.source_strings) total_words.append(project.stats.source_words) context['total_translations'] = totals['translated__sum'] context['total_suggestions'] = totals['suggested__sum'] context['total_users'] = totals['id__count'] context['total_strings'] = sum(total_strings) context['total_units'] = Unit.objects.count() context['total_words'] = sum(total_words) context['total_languages'] = Language.objects.filter( translation__pk__gt=0 ).distinct().count() context['total_checks'] = Check.objects.count() context['ignored_checks'] = Check.objects.filter(ignore=True).count() top_translations = Profile.objects.order_by('-translated')[:10] top_suggestions = Profile.objects.order_by('-suggested')[:10] context['top_translations'] = top_translations.select_related('user') context['top_suggestions'] = top_suggestions.select_related('user') return render( request, 'stats.html', context )
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', {}, )
def edit_dictionary(request, project, lang, pk): prj = get_project(request, project) if not request.user.has_perm('glossary.edit', prj): raise PermissionDenied() lang = get_object_or_404(Language, code=lang) word = get_object_or_404(Dictionary, project=prj, language=lang, id=pk) if request.method == 'POST': form = WordForm(request.POST) if form.is_valid(): word.edit(request, form.cleaned_data['source'], form.cleaned_data['target']) return redirect('show_dictionary', project=prj.slug, lang=lang.code) else: form = WordForm(initial={'source': word.source, 'target': word.target}) last_changes = Change.objects.last_changes(request.user).filter(dictionary=word)[ :10 ] return render( request, 'edit_dictionary.html', { 'title': dict_title(prj, lang), 'project': prj, 'language': lang, 'form': form, 'last_changes': last_changes, 'last_changes_url': urlencode( ( ('project', prj.slug), ('lang', lang.code), ('action', Change.ACTION_DICTIONARY_NEW), ('action', Change.ACTION_DICTIONARY_EDIT), ('action', Change.ACTION_DICTIONARY_UPLOAD), ) ), }, )
def load_zen(request, project, subproject, lang): ''' Loads additional units for zen editor. ''' translation = get_translation(request, project, subproject, lang) search_result, unitdata = get_zen_unitdata(translation, request) # Handle redirects if isinstance(search_result, HttpResponse): return search_result return render( request, 'zen-units.html', { 'object': translation, 'unitdata': unitdata, 'search_query': search_result['query'], 'search_id': search_result['search_id'], 'last_section': search_result['last_section'], } )
def load_zen(request, project, component, lang): """Load additional units for zen editor.""" obj, project, unit_set = parse_params(request, project, component, lang) search_result, unitdata = get_zen_unitdata(obj, unit_set, request) # Handle redirects if isinstance(search_result, HttpResponse): return search_result return render( request, "zen-units.html", { "object": obj, "project": project, "unitdata": unitdata, "search_query": search_result["query"], "search_url": search_result["url"], "last_section": search_result["last_section"], }, )
def browse(request, project, component, lang): """Strings browsing.""" obj, project, unit_set = parse_params(request, project, component, lang) search_result = search(obj, project, unit_set, request, blank=True) offset = search_result["offset"] page = 20 units = unit_set.get_ordered( search_result["ids"][(offset - 1) * page : (offset - 1) * page + page] ) base_unit_url = "{}?{}&offset=".format( reverse("browse", kwargs=obj.get_reverse_url_kwargs()), search_result["url"], ) num_results = ceil(len(search_result["ids"]) / page) sort = get_sort_name(request, obj) return render( request, "browse.html", { "object": obj, "project": project, "units": units, "search_query": search_result["query"], "search_url": search_result["url"], "search_form": search_result["form"].reset_offset(), "filter_count": num_results, "filter_pos": offset, "filter_name": search_result["name"], "first_unit_url": base_unit_url + "1", "last_unit_url": base_unit_url + str(num_results), "next_unit_url": base_unit_url + str(offset + 1), "prev_unit_url": base_unit_url + str(offset - 1), "sort_name": sort["name"], "sort_query": sort["query"], }, )
def dashboard_anonymous(request): """Home page of Weblate showing list of projects for anonymous user.""" top_project_ids = cache.get("dashboard-anonymous-projects") if top_project_ids is None: top_projects = sorted( prefetch_stats(request.user.allowed_projects), key=lambda prj: -prj.stats.monthly_changes, )[:20] top_project_ids = {p.id for p in top_projects} cache.set("dashboard-anonymous-projects", top_project_ids, 3600) top_projects = request.user.allowed_projects.filter(id__in=top_project_ids) return render( request, "dashboard/anonymous.html", { "top_projects": prefetch_project_flags(top_projects), "all_projects": Metric.objects.get_current(Metric.SCOPE_GLOBAL, 0, name="projects")["projects"], }, )
def manage_access(request, project): """User management view.""" obj = get_project(request, project) if not can_manage_acl(request.user, obj): raise PermissionDenied() if can_edit_access_control(request.user, obj): access_form = ProjectAccessForm(instance=obj) else: access_form = DisabledProjectAccessForm(instance=obj) return render( request, 'manage-access.html', { 'object': obj, 'project': obj, 'groups': obj.all_groups(), 'add_user_form': UserManageForm(), 'access_form': access_form, } )
def change_project(request, project): obj = get_project(request, project) if not can_edit_project(request.user, obj): raise Http404() if request.method == 'POST': settings_form = ProjectSettingsForm(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(instance=obj) return render(request, 'project-settings.html', { 'object': obj, 'settings_form': settings_form, })
def stats(request): """Various stats about Weblate""" context = {} context['title'] = _('Weblate statistics') totals = Profile.objects.aggregate(Sum('translated'), Sum('suggested'), Count('id')) total_strings = [] total_words = [] for project in SubProject.objects.iterator(): try: translation_obj = project.translation_set.all()[0] total_strings.append(translation_obj.total) total_words.append(translation_obj.total_words) except IndexError: pass context['total_translations'] = totals['translated__sum'] context['total_suggestions'] = totals['suggested__sum'] context['total_users'] = totals['id__count'] context['total_strings'] = sum(total_strings) context['total_units'] = Unit.objects.count() context['total_words'] = sum(total_words) context['total_languages'] = Language.objects.filter( translation__total__gt=0).distinct().count() context['total_checks'] = Check.objects.count() context['ignored_checks'] = Check.objects.filter(ignore=True).count() top_translations = Profile.objects.order_by('-translated')[:10] top_suggestions = Profile.objects.order_by('-suggested')[:10] context['top_translations'] = top_translations.select_related('user') context['top_suggestions'] = top_suggestions.select_related('user') return render(request, 'stats.html', context)
def review_source(request, project, component): """Listing of source strings to review.""" obj, source = get_source(request, project, component) # Grab search type and page number rqtype = request.GET.get('type', 'all') try: id_hash = checksum_to_hash(request.GET.get('checksum', '')) except ValueError: id_hash = None ignored = 'ignored' in request.GET expand = False query_string = {'type': rqtype} if ignored: query_string['ignored'] = 'true' # Filter units: if id_hash: sources = source.unit_set.filter(id_hash=id_hash) expand = True else: sources = source.unit_set.filter_type(rqtype, source.component.project, source.language, ignored) sources = get_paginator(request, sources) return render( request, 'source-review.html', { 'object': obj, 'project': obj.project, 'source': source, 'page_obj': sources, 'query_string': urlencode(query_string), 'ignored': ignored, 'expand': expand, 'title': _('Review source strings in %s') % force_text(obj), })
def home(request): """ Home page of Weblate showing list of projects, stats and user links if logged in. """ if 'show_set_password' in request.session: messages.warning( request, _('You have activated your account, now you should set ' 'the password to be able to login next time.')) return redirect('password') wb_messages = WhiteboardMessage.objects.all() projects = Project.objects.all_acl(request.user) if projects.count() == 1: projects = SubProject.objects.filter( project=projects[0]).select_related() # Warn about not filled in username (usually caused by migration of # users from older system if not request.user.is_anonymous() and request.user.first_name == '': messages.warning(request, _('Please set your full name in your profile.')) # Some stats last_changes = Change.objects.last_changes(request.user)[:10] return render( request, 'index.html', { 'projects': projects, 'last_changes': last_changes, 'last_changes_url': '', 'search_form': SiteSearchForm(), 'whiteboard_messages': wb_messages, })
def dashboard_anonymous(request): """Home page of Weblate showing list of projects for anonymous user.""" top_project_ids = cache.get("dashboard-anonymous-projects") if top_project_ids is None: top_projects = sorted( prefetch_stats(request.user.allowed_projects), key=lambda prj: -prj.stats.monthly_changes, )[:20] cache.set("dashboard-anonymous-projects", {p.id for p in top_projects}, 3600) else: # The allowed_projects is already fetched, so filter it in Python # instead of doing additional query top_projects = [ p for p in request.user.allowed_projects if p.id in top_project_ids ] return render( request, "dashboard/anonymous.html", { "top_projects": top_projects, "all_projects": len(request.user.allowed_projects), }, )
def manage_access(request, project): """User management view.""" obj = get_project(request, project) if not request.user.has_perm("project.permissions", obj): raise PermissionDenied() return render( request, "manage-access.html", { "object": obj, "project": obj, "groups": Group.objects.for_project(obj), "all_users": User.objects.for_project(obj), "blocked_users": obj.userblock_set.select_related("user"), "add_user_form": UserManageForm(), "block_user_form": UserBlockForm( initial={"user": request.GET.get("block_user")} ), "invite_user_form": InviteUserForm(), "ssh_key": get_key_data(), }, )
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 show_engage(request, project, lang=None): # Get project object, skipping ACL obj = get_project(request, project, skip_acl=True) # Handle language parameter if lang is not None: language = get_object_or_404(Language, code=lang) else: language = None full_stats = obj.stats if language: try_set_language(lang) stats_obj = full_stats.get_single_language_stats(language) else: stats_obj = full_stats return render( request, "engage.html", { "allow_index": True, "object": obj, "project": obj, "full_stats": full_stats, "languages": stats_obj.languages, "total": obj.stats.source_strings, "percent": stats_obj.translated_percent, "language": language, "project_link": mark_safe( '<a href="{}">{}</a>'.format( escape(obj.get_absolute_url()), escape(obj.name) ) ), "title": _("Get involved in {0}!").format(obj), }, )
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}, )
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())), }, )
def denied(request, exception=None): return render(request, "403.html", {"title": _("Permission Denied")}, status=403)