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] translations = prefetch_stats(list(obj.translation_set.prefetch())) # Show ghost translations for user languages add_ghost_translations(obj, user, translations, GhostTranslation) translations = sort_unicode( translations, lambda x: "{}-{}".format(user.profile.get_language_order(x.language), x .language), ) return render( request, "component.html", { "allow_index": True, "object": obj, "project": obj.project, "translations": translations, "reports_form": ReportsForm(), "last_changes": last_changes, "last_changes_url": urlencode({ "component": obj.slug, "project": obj.project.slug }), "replace_form": optional_form(ReplaceForm, user, "unit.edit", obj), "bulk_state_form": optional_form( BulkEditForm, user, "translation.auto", obj, user=user, obj=obj, project=obj.project, auto_id="id_bulk_%s", ), "announcement_form": optional_form(AnnouncementForm, user, "component.edit", obj), "delete_form": optional_form( ComponentDeleteForm, 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.all_alerts, }, )
def show_translation(request, project, component, lang): obj = get_translation(request, project, component, lang) obj.stats.ensure_all() last_changes = Change.objects.prefetch().order().filter( translation=obj)[:10] user = request.user # Get form form = get_upload_form(user, obj) search_form = SearchForm(request.user) other_translations = prefetch_stats( list(Translation.objects.prefetch().filter( component__project=obj.component.project, language=obj.language).exclude(pk=obj.pk))) # Include ghost translations for other components existing = { translation.component.slug for translation in other_translations } existing.add(obj.component.slug) for component in obj.component.project.component_set.exclude( slug__in=existing): if component.can_add_new_language(user): other_translations.append(GhostTranslation(component, obj.language)) return render( request, "translation.html", { "allow_index": True, "object": obj, "project": obj.component.project, "form": form, "download_form": DownloadForm(auto_id="id_dl_%s"), "autoform": optional_form( AutoForm, user, "translation.auto", obj, obj=obj.component), "search_form": search_form, "replace_form": optional_form(ReplaceForm, user, "unit.edit", obj), "bulk_state_form": optional_form( BulkEditForm, user, "translation.auto", obj, user=user, obj=obj, project=obj.component.project, auto_id="id_bulk_%s", ), "new_unit_form": NewUnitForm(user, initial={"value": Unit(translation=obj, id_hash=-1)}), "announcement_form": optional_form(AnnouncementForm, user, "component.edit", obj), "delete_form": optional_form(TranslationDeleteForm, user, "translation.delete", obj, obj=obj), "last_changes": last_changes, "last_changes_url": urlencode(obj.get_reverse_url_kwargs()), "other_translations": other_translations, "exporters": list_exporters(obj), }, )
def search(request, project=None, component=None, lang=None): """Perform site-wide search on units.""" is_ratelimited = not check_rate_limit("search", request) search_form = SearchForm(user=request.user, data=request.GET) sort = get_sort_name(request) context = {"search_form": search_form} if component: obj = get_component(request, project, component) context["component"] = obj context["project"] = obj.project context["back_url"] = obj.get_absolute_url() elif project: obj = get_project(request, project) context["project"] = obj context["back_url"] = obj.get_absolute_url() else: obj = None context["back_url"] = None if lang: s_language = get_object_or_404(Language, code=lang) context["language"] = s_language if obj: if component: context["back_url"] = obj.translation_set.get( language=s_language).get_absolute_url() else: context["back_url"] = reverse("project-language", kwargs={ "project": project, "lang": lang }) else: context["back_url"] = s_language.get_absolute_url() if not is_ratelimited and request.GET and search_form.is_valid(): # This is ugly way to hide query builder when showing results search_form = SearchForm(user=request.user, data=request.GET, show_builder=False) search_form.is_valid() # Filter results by ACL units = Unit.objects.prefetch_full().prefetch() if component: units = units.filter(translation__component=obj) elif project: units = units.filter(translation__component__project=obj) else: units = units.filter_access(request.user) units = units.search(search_form.cleaned_data.get("q", "")).distinct() if lang: units = units.filter(translation__language=context["language"]) units = get_paginator(request, units.order_by_request(search_form.cleaned_data)) # Rebuild context from scratch here to get new form context = { "search_form": search_form, "show_results": True, "page_obj": units, "title": _("Search for %s") % (search_form.cleaned_data["q"]), "query_string": search_form.urlencode(), "search_query": search_form.cleaned_data["q"], "search_items": search_form.items(), "filter_name": search_form.get_name(), "sort_name": sort["name"], "sort_query": sort["query"], } elif is_ratelimited: messages.error(request, _("Too many search queries, please try again later.")) elif request.GET: messages.error(request, _("Invalid search query!")) show_form_errors(request, search_form) return render(request, "search.html", context)
def show_project(request, project): obj = get_project(request, project) user = request.user last_changes = Change.objects.prefetch().order().filter(project=obj)[:10] last_announcements = (Change.objects.prefetch().order().filter( project=obj, action=Change.ACTION_ANNOUNCEMENT)[:10]) language_stats = obj.stats.get_language_stats() # Show ghost translations for user languages component = None for component in obj.component_set.all(): if component.can_add_new_language(user): break if component: add_ghost_translations(component, user, language_stats, GhostProjectLanguageStats) language_stats = sort_unicode( language_stats, lambda x: "{}-{}".format(user.profile.get_language_order(x.language), x .language), ) # Paginate components of project. all_components = obj.component_set.prefetch().order() components = prefetch_stats(get_paginator(request, all_components)) return render( request, "project.html", { "allow_index": True, "object": obj, "project": obj, "last_changes": last_changes, "last_announcements": last_announcements, "reports_form": ReportsForm(), "last_changes_url": urlencode({"project": obj.slug}), "language_stats": language_stats, "search_form": SearchForm(request.user), "announcement_form": optional_form(AnnouncementForm, user, "project.edit", obj), "delete_form": optional_form( ProjectDeleteForm, 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( BulkEditForm, user, "translation.auto", obj, user=user, obj=obj, project=obj, auto_id="id_bulk_%s", ), "components": components, "licenses": obj.component_set.exclude(license="").order_by("license"), }, )
def show_translation(request, project, component, lang): obj = get_translation(request, project, component, lang) component = obj.component project = component.project obj.stats.ensure_all() last_changes = obj.change_set.prefetch().order()[:10] user = request.user # Get form form = get_upload_form(user, obj) search_form = SearchForm(request.user, language=obj.language) # Translations to same language from other components in this project other_translations = prefetch_stats( list(Translation.objects.prefetch().filter( component__project=project, language=obj.language).exclude(pk=obj.pk))) # Include ghost translations for other components, this # adds quick way to create translations in other components existing = { translation.component.slug for translation in other_translations } existing.add(component.slug) for test_component in project.child_components.filter_access(user).exclude( slug__in=existing): if test_component.can_add_new_language(user, fast=True): other_translations.append( GhostTranslation(test_component, obj.language)) # Limit the number of other components displayed to 10, preferring untranslated ones other_translations = sorted(other_translations, key=lambda t: t.stats.translated_percent)[:10] return render( request, "translation.html", { "allow_index": True, "object": obj, "project": project, "form": form, "download_form": DownloadForm(auto_id="id_dl_%s"), "autoform": optional_form( AutoForm, user, "translation.auto", obj, obj=component), "search_form": search_form, "replace_form": optional_form(ReplaceForm, user, "unit.edit", obj), "bulk_state_form": optional_form( BulkEditForm, user, "translation.auto", obj, user=user, obj=obj, project=project, auto_id="id_bulk_%s", ), "new_unit_form": get_new_unit_form(obj, user), "announcement_form": optional_form(AnnouncementForm, user, "component.edit", obj), "delete_form": optional_form(TranslationDeleteForm, user, "translation.delete", obj, obj=obj), "last_changes": last_changes, "last_changes_url": urlencode(obj.get_reverse_url_kwargs()), "other_translations": other_translations, "exporters": EXPORTERS.list_exporters(obj), }, )
def show_translation(request, project, component, lang): obj = get_translation(request, project, component, lang) obj.stats.ensure_all() last_changes = Change.objects.for_translation(obj)[:10] # Get form form = get_upload_form(request.user, obj) # 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 # Is user allowed to do automatic translation? if request.user.has_perm('translation.auto', obj): 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={'exclude_user': request.user.username}) if request.user.has_perm('unit.edit', obj): replace_form = ReplaceForm() else: replace_form = None return render( request, 'translation.html', { 'allow_index': True, 'object': obj, 'project': obj.component.project, 'form': form, 'download_form': DownloadForm(), 'autoform': autoform, 'search_form': search_form, 'review_form': review_form, 'replace_form': replace_form, 'mass_state_form': mass_state_form, 'new_unit_form': NewUnitForm( request.user, initial={ 'value': Unit(translation=obj, id_hash=-1), }, ), 'last_changes': last_changes, 'last_changes_url': urlencode(obj.get_reverse_url_kwargs()), 'show_only_component': True, 'other_translations': prefetch_stats(Translation.objects.prefetch().filter( component__project=obj.component.project, language=obj.language, ).exclude(pk=obj.pk)), 'exporters': list_exporters(), })
def show_project(request, project): obj = get_project(request, project) obj.stats.ensure_basic() user = request.user last_changes = obj.change_set.prefetch().order()[:10] last_announcements = (Change.objects.prefetch().order().filter( project=obj, action=Change.ACTION_ANNOUNCEMENT)[:10]) all_components = obj.child_components.filter_access( user).prefetch().order() for component in all_components: component.is_shared = None if component.project == obj else component.project language_stats = obj.stats.get_language_stats() # Show ghost translations for user languages component = None for component in all_components: if component.can_add_new_language(user, fast=True): break if component: add_ghost_translations( component, user, language_stats, GhostProjectLanguageStats, is_shared=component.is_shared, ) language_stats = sort_unicode( language_stats, lambda x: "{}-{}".format(user.profile.get_language_order(x.language), x .language), ) components = prefetch_tasks(prefetch_stats(all_components)) return render( request, "project.html", { "allow_index": True, "object": obj, "project": obj, "last_changes": last_changes, "last_announcements": last_announcements, "reports_form": ReportsForm(), "last_changes_url": urlencode({"project": obj.slug}), "language_stats": [stat.obj or stat for stat in language_stats], "search_form": SearchForm(request.user), "announcement_form": optional_form(AnnouncementForm, user, "project.edit", obj), "delete_form": optional_form( ProjectDeleteForm, 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( BulkEditForm, user, "translation.auto", obj, user=user, obj=obj, project=obj, auto_id="id_bulk_%s", ), "components": components, "licenses": sorted( (component for component in all_components if component.license), key=lambda component: component.license, ), }, )
def search(request, project=None, component=None, lang=None): """Perform site-wide search on units.""" is_ratelimited = not check_rate_limit("search", request) search_form = SearchForm(request.user, request.GET) sort = get_sort_name(request) context = {"search_form": search_form} if component: obj = get_component(request, project, component) context["component"] = obj context["project"] = obj.project context["back_url"] = obj.get_absolute_url() elif project: obj = get_project(request, project) context["project"] = obj context["back_url"] = obj.get_absolute_url() else: obj = None context["back_url"] = None if lang: s_language = get_object_or_404(Language, code=lang) context["language"] = s_language if obj: if component: context["back_url"] = obj.translation_set.get( language=s_language).get_absolute_url() else: context["back_url"] = reverse("project-language", kwargs={ "project": project, "lang": lang }) else: context["back_url"] = s_language.get_absolute_url() if not is_ratelimited and request.GET and search_form.is_valid(): # Filter results by ACL if component: units = Unit.objects.filter(translation__component=obj) elif project: units = Unit.objects.filter(translation__component__project=obj) else: units = Unit.objects.filter( translation__component__project_id__in=request.user. allowed_project_ids) units = units.search(search_form.cleaned_data.get("q", "")).distinct() if lang: units = units.filter(translation__language=context["language"]) units = get_paginator(request, units.order_by_request(search_form.cleaned_data)) 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"] context["search_items"] = search_form.items() context["filter_name"] = search_form.get_name() context["sort_name"] = sort["name"] context["sort_query"] = sort["query"] elif is_ratelimited: messages.error(request, _("Too many search queries, please try again later.")) elif request.GET: messages.error(request, _("Invalid search query!")) show_form_errors(request, search_form) return render(request, "search.html", context)
def search(translation, request): ''' Performs search or returns cached search results. ''' # Already performed search if 'sid' in request.GET: # Grab from session storage search_id = 'search_%s' % request.GET['sid'] # Check if we know the search if search_id not in request.session: messages.error(request, _('Invalid search string!')) return redirect(translation) return request.session[search_id] # Possible new search rqtype = request.GET.get('type', 'all') search_form = SearchForm(request.GET) review_form = ReviewForm(request.GET) search_query = None if review_form.is_valid(): # Review allunits = translation.unit_set.review( review_form.cleaned_data['date'], request.user ) formatted_date = formats.date_format( review_form.cleaned_data['date'], 'SHORT_DATE_FORMAT' ) name = _('Review of translations since %s') % formatted_date elif search_form.is_valid(): # Apply search conditions allunits = translation.unit_set.search( search_form.cleaned_data, ) search_query = search_form.cleaned_data['q'] name = get_search_name( search_form.cleaned_data['search'], search_query, ) else: # Error reporting if 'date' in request.GET: show_form_errors(request, review_form) elif 'q' in request.GET: show_form_errors(request, search_form) # Filtering by type allunits = translation.unit_set.filter_type( rqtype, translation, ignored='ignored' in request.GET ) name = get_filter_name(rqtype) # Grab unit IDs unit_ids = list(allunits.values_list('id', flat=True)) # Check empty search results if len(unit_ids) == 0: messages.warning(request, _('No string matched your search!')) return redirect(translation) # Checksum unit access offset = 0 if 'checksum' in request.GET: try: unit = allunits.filter(checksum=request.GET['checksum'])[0] offset = unit_ids.index(unit.id) except (Unit.DoesNotExist, IndexError): messages.warning(request, _('No string matched your search!')) return redirect(translation) # Remove old search results cleanup_session(request.session) # Store in cache and return search_id = str(uuid.uuid1()) search_result = { 'query': search_query, 'name': name, 'ids': unit_ids, 'search_id': search_id, 'ttl': int(time.time()) + 86400, 'offset': offset, } request.session['search_%s' % search_id] = search_result return search_result
def translate(request, project, subproject, lang): ''' Generic entry point for translating, suggesting and searching. ''' translation = get_translation(request, project, subproject, lang) # Check locks project_locked, user_locked, own_lock = translation.is_locked( request, True ) locked = project_locked or user_locked # Search results search_result = search(translation, request) # Handle redirects if isinstance(search_result, HttpResponse): return search_result # Get numer of results num_results = len(search_result['ids']) # Search offset try: offset = int(request.GET.get('offset', search_result.get('offset', 0))) except ValueError: offset = 0 # Check boundaries if offset < 0 or offset >= num_results: messages.info(request, _('You have reached end of translating.')) # Delete search del request.session['search_%s' % search_result['search_id']] # Redirect to translation return redirect(translation) # Some URLs we will most likely use base_unit_url = '%s?sid=%s&offset=' % ( translation.get_translate_url(), search_result['search_id'], ) this_unit_url = base_unit_url + str(offset) next_unit_url = base_unit_url + str(offset + 1) response = None # Any form submitted? if request.method == 'POST' and not project_locked: # Handle accepting/deleting suggestions if ('accept' not in request.POST and 'delete' not in request.POST and 'upvote' not in request.POST and 'downvote' not in request.POST): response = handle_translate( translation, request, user_locked, this_unit_url, next_unit_url ) elif not locked: response = handle_suggestions( translation, request, this_unit_url ) # Handle translation merging elif 'merge' in request.GET and not locked: response = handle_merge( translation, request, next_unit_url ) # Handle reverting elif 'revert' in request.GET and not locked: response = handle_revert( translation, request, this_unit_url ) # Pass possible redirect further if response is not None: return response # Grab actual unit try: unit = translation.unit_set.get(pk=search_result['ids'][offset]) except Unit.DoesNotExist: # Can happen when using SID for other translation messages.error(request, _('Invalid search string!')) return redirect(translation) # Show secondary languages for logged in users if request.user.is_authenticated(): secondary = request.user.profile.get_secondary_units(unit) else: secondary = None # Spam protection antispam = AntispamForm() # Prepare form form = TranslationForm(translation, unit) return render_to_response( 'translate.html', RequestContext( request, { 'this_unit_url': this_unit_url, 'first_unit_url': base_unit_url + '0', 'last_unit_url': base_unit_url + str(num_results - 1), 'next_unit_url': next_unit_url, 'prev_unit_url': base_unit_url + str(offset - 1), 'object': translation, 'unit': unit, 'total': translation.unit_set.all().count(), 'search_id': search_result['search_id'], 'search_query': search_result['query'], 'offset': offset, 'filter_name': search_result['name'], 'filter_count': num_results, 'filter_pos': offset + 1, 'form': form, 'antispam': antispam, 'comment_form': CommentForm(), 'search_form': SearchForm(), 'update_lock': own_lock, 'secondary': secondary, 'locked': locked, 'user_locked': user_locked, 'project_locked': project_locked, }, ) )
def show_translation(request, project, subproject, lang): obj = get_translation(request, project, subproject, lang) obj.stats.ensure_all() last_changes = Change.objects.for_translation(obj)[:10] # Get form form = get_upload_form(request.user, obj) # 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={'exclude_user': request.user.username}) if can_translate(request.user, translation=obj): replace_form = ReplaceForm() mass_state_form = MassStateForm(request.user, obj) else: replace_form = None mass_state_form = None return render( request, 'translation.html', { 'allow_index': True, 'object': obj, 'project': obj.subproject.project, 'form': form, 'autoform': autoform, 'search_form': search_form, 'review_form': review_form, 'replace_form': replace_form, 'mass_state_form': mass_state_form, 'new_unit_form': NewUnitForm( request.user, initial={ 'value': Unit(translation=obj, id_hash=-1), }, ), 'last_changes': last_changes, 'last_changes_url': urlencode(obj.get_kwargs()), 'show_only_component': True, 'pending_fulltext': obj.unit_set.filter(id__in=IndexUpdate.objects.filter( to_delete=False).values('unitid')).exists(), 'other_translations': prefetch_stats(Translation.objects.prefetch().filter( subproject__project=obj.subproject.project, language=obj.language, ).exclude(pk=obj.pk)), })