def process_view(self, request, view_func, view_args, view_kwargs): """Check request whether user has agreed to TOS.""" # We intercept only GET requests for authenticated users if request.method != 'GET' or not request.user.is_authenticated: return None # Some paths are ignored if self.matcher.match(request.path): return None # Check TOS agreement agreement = Agreement.objects.get_or_create(user=request.user)[0] if not agreement.is_current(): messages.info( request, _( 'We have new version of the Terms of Service document, ' 'please read it and confirm that you agree with it.' ) ) return redirect( '{0}?{1}'.format( reverse('legal:confirm'), urlencode({'next': request.get_full_path()}) ) ) # Explicitly return None for all non-matching requests return None
def weblate_logout(request): """Logout handler, just wrapper around standard Django logout.""" messages.info(request, _('Thanks for using Weblate!')) return auth_views.logout( request, next_page=reverse('home'), )
def logout(self, request, extra_context=None): if request.method == 'POST': messages.info(request, _('Thanks for using Weblate!')) request.current_app = self.name return LogoutView.as_view(next_page=reverse('admin:login'))(request) context = self.each_context(request) context['title'] = _('Logout') return render(request, 'admin/logout-confirm.html', context)
def perform_suggestion(unit, form, request): """Handle suggesion saving.""" if form.cleaned_data['target'][0] == '': messages.error(request, _('Your suggestion is empty!')) # Stay on same entry return False elif not request.user.has_perm('suggestion.add', unit.translation): # Need privilege to add messages.error( request, _('You don\'t have privileges to add suggestions!') ) # Stay on same entry return False elif not request.user.is_authenticated: # Spam check if is_spam('\n'.join(form.cleaned_data['target']), request): messages.error( request, _('Your suggestion has been identified as spam!') ) return False # Invite user to become translator if there is nobody else # and the project is accepting translations translation = unit.translation if (not translation.component.suggestion_voting or not translation.component.suggestion_autoaccept): recent_changes = Change.objects.content(True).filter( translation=translation, ).exclude( user=None ) if not recent_changes.exists(): messages.info(request, _( 'There is currently no active translator for this ' 'translation, please consider becoming a translator ' 'as your suggestion might otherwise remain unreviewed.' )) messages.info(request, mark_safe( '<a href="{0}">{1}</a>'.format( escape(get_doc_url('user/translating')), escape(_( 'See our documentation for more information ' 'on translating using Weblate.' )), ) )) # Create the suggestion result = Suggestion.objects.add( unit, join_plural(form.cleaned_data['target']), request, request.user.has_perm('suggestion.vote', unit) ) if not result: messages.error(request, _('Your suggestion already exists!')) return result
def perform_translation(unit, form, request): """Handle translation and stores it to a backend.""" # Remember old checks oldchecks = set( unit.active_checks().values_list('check', flat=True) ) # Run AutoFixes on user input if not unit.translation.is_template: new_target, fixups = fix_target(form.cleaned_data['target'], unit) else: new_target = form.cleaned_data['target'] fixups = [] # Save saved = unit.translate( request, new_target, form.cleaned_data['state'] ) # Should we skip to next entry if not saved: revert_rate_limit('translate', request) return True # Warn about applied fixups if fixups: messages.info( request, _('Following fixups were applied to translation: %s') % ', '.join([force_text(f) for f in fixups]) ) # Get new set of checks newchecks = set( unit.active_checks().values_list('check', flat=True) ) # Did we introduce any new failures? if saved and newchecks > oldchecks: # Show message to user messages.error( request, _( 'The translation has been saved, however there ' 'are some newly failing checks: {0}' ).format( ', '.join( [force_text(CHECKS[check].name) for check in newchecks] ) ) ) # Stay on same entry return False return True
def perform_translation(unit, form, request): """Handle translation and stores it to a backend.""" # Remember old checks oldchecks = set( unit.active_checks().values_list('check', flat=True) ) # Run AutoFixes on user input if not unit.translation.is_template(): new_target, fixups = fix_target(form.cleaned_data['target'], unit) else: new_target = form.cleaned_data['target'] fixups = [] # Save saved = unit.translate( request, new_target, form.cleaned_data['fuzzy'] ) # Warn about applied fixups if len(fixups) > 0: messages.info( request, _('Following fixups were applied to translation: %s') % ', '.join([force_text(f) for f in fixups]) ) # Get new set of checks newchecks = set( unit.active_checks().values_list('check', flat=True) ) # Did we introduce any new failures? if saved and newchecks > oldchecks: # Show message to user messages.error( request, _( 'Some checks have failed on your translation: {0}' ).format( ', '.join( [force_text(CHECKS[check].name) for check in newchecks] ) ) ) # Stay on same entry return False return True
def dispatch(self, request, *args, **kwargs): # Redirect logged in users to profile if request.user.is_authenticated: return redirect_profile() # Redirect if there is only one backend auth_backends = list( load_backends(social_django.utils.BACKENDS).keys() ) if len(auth_backends) == 1 and auth_backends[0] != 'email': return redirect_single(request, auth_backends[0]) if 'next' in request.GET: messages.info(request, _('Log in to use Weblate.')) return super(WeblateLoginView, self).dispatch(request, *args, **kwargs)
def delete_comment(request, pk): """Delete comment.""" comment_obj = get_object_or_404(Comment, pk=pk) request.user.check_access(comment_obj.project) if not request.user.has_perm('comment.delete', comment_obj, comment_obj.project): raise PermissionDenied() units = comment_obj.related_units if units.exists(): fallback_url = units[0].get_absolute_url() else: fallback_url = comment_obj.project.get_absolute_url() comment_obj.delete() messages.info(request, _('Translation comment has been deleted.')) return redirect_next(request.POST.get('next'), fallback_url)
def delete_comment(request, pk): """Delete comment.""" comment_obj = get_object_or_404(Comment, pk=pk) check_access(request, comment_obj.project) if not can_delete_comment(request.user, comment_obj.project): raise PermissionDenied() units = get_related_units(comment_obj) if units.exists(): fallback_url = units[0].get_absolute_url() else: fallback_url = comment_obj.project.get_absolute_url() comment_obj.delete() messages.info(request, _('Translation comment has been deleted.')) return redirect_next(request.POST.get('next'), fallback_url)
def fixup_profile(self, request): fields = set() if not self.language: self.language = get_language() fields.add("language") allowed = { clist.pk for clist in self.allowed_dashboard_component_lists } if not allowed and self.dashboard_view in ( Profile.DASHBOARD_COMPONENT_LIST, Profile.DASHBOARD_COMPONENT_LISTS, ): self.dashboard_view = Profile.DASHBOARD_WATCHED fields.add("dashboard_view") if self.dashboard_component_list_id and ( self.dashboard_component_list_id not in allowed or self.dashboard_view != Profile.DASHBOARD_COMPONENT_LIST): self.dashboard_component_list = None self.dashboard_view = Profile.DASHBOARD_WATCHED fields.add("dashboard_view") fields.add("dashboard_component_list") if (not self.dashboard_component_list_id and self.dashboard_view == Profile.DASHBOARD_COMPONENT_LIST): self.dashboard_view = Profile.DASHBOARD_WATCHED fields.add("dashboard_view") if not self.languages.exists(): language = Language.objects.get_request_language(request) if language: self.languages.add(language) messages.info( request, _("Added %(language)s to your translated languages. " "You can adjust them in the settings.") % {"language": language}, ) if fields: self.save(update_fields=fields)
def perform_translation(unit, form, request): """Handle translation and stores it to a backend.""" # Remember old checks oldchecks = unit.all_checks_names # Save saved = unit.translate( request.user, form.cleaned_data["target"], form.cleaned_data["state"] ) # Warn about applied fixups if unit.fixups: messages.info( request, _("Following fixups were applied to translation: %s") % ", ".join(force_str(f) for f in unit.fixups), ) # No change edit - should we skip to next entry if not saved: revert_rate_limit("translate", request) return True # Get new set of checks newchecks = unit.all_checks_names # Did we introduce any new failures? if ( saved and form.cleaned_data["state"] >= STATE_TRANSLATED and newchecks > oldchecks ): # Show message to user messages.error( request, _( "The translation has been saved, however there " "are some newly failing checks: {0}" ).format(", ".join(force_str(CHECKS[check].name) for check in newchecks)), ) # Stay on same entry return False return True
def perform_translation(unit, form, request): """Handle translation and stores it to a backend.""" # Remember old checks oldchecks = set(unit.active_checks().values_list('check', flat=True)) # Run AutoFixes on user input if not unit.translation.is_template: new_target, fixups = fix_target(form.cleaned_data['target'], unit) else: new_target = form.cleaned_data['target'] fixups = [] # Save saved = unit.translate(request.user, new_target, form.cleaned_data['state']) # Should we skip to next entry if not saved: revert_rate_limit('translate', request) return True # Warn about applied fixups if fixups: messages.info( request, _('Following fixups were applied to translation: %s') % ', '.join([force_text(f) for f in fixups])) # Get new set of checks newchecks = set(unit.active_checks().values_list('check', flat=True)) # Did we introduce any new failures? if saved and newchecks > oldchecks: # Show message to user messages.error( request, _('The translation has been saved, however there ' 'are some newly failing checks: {0}').format(', '.join( [force_text(CHECKS[check].name) for check in newchecks]))) # Stay on same entry return False return True
def create_token(request, project): """Create project token.""" obj = get_project(request, project) if not request.user.has_perm("project.permissions", obj): raise PermissionDenied() form = ProjectTokenCreateForm(obj, request.POST) if form.is_valid(): token = form.save() messages.info( request, render_to_string("trans/projecttoken-created.html", {"token": token.auth_token.key}), ) else: show_form_errors(request, form) return redirect_param("manage-access", "#api", project=obj.slug)
def perform_suggestion(unit, form, request): """Handle suggesion saving.""" if form.cleaned_data['target'][0] == '': messages.error(request, _('Your suggestion is empty!')) # Stay on same entry return False elif not can_suggest(request.user, unit.translation): # Need privilege to add messages.error(request, _('You don\'t have privileges to add suggestions!')) # Stay on same entry return False # Invite user to become translator if there is nobody else # and the project is accepting translations translation = unit.translation if (not translation.subproject.suggestion_voting or not translation.subproject.suggestion_autoaccept): recent_changes = Change.objects.content(True).filter( translation=translation, ).exclude(user=None) if not recent_changes.exists(): messages.info( request, _('There is currently no active translator for this ' 'translation, please consider becoming a translator ' 'as your suggestion might otherwise remain unreviewed.')) messages.info( request, mark_safe('<a href="{0}">{1}</a>'.format( escape(get_doc_url('user/translating')), escape( _('See our documentation for more information ' 'on translating using Weblate.')), ))) # Create the suggestion result = Suggestion.objects.add( unit, join_plural(form.cleaned_data['target']), request, can_vote_suggestion(request.user, unit.translation)) if not result: messages.error(request, _('Your suggestion already exists!')) return result
def handle_payment(self, request): try: payment = Payment.objects.select_for_update().get( uuid=request.GET["payment"], customer__user_id=request.user.id, customer__origin=get_origin(), ) except (Payment.DoesNotExist, ValidationError): messages.error(request, _("No matching payment found.")) return redirect("create-billing") if payment.state in (Payment.ACCEPTED, Payment.PROCESSED): if payment.state == Payment.ACCEPTED: handle_received_payment(payment) messages.success( request, _("Thank you for purchasing a hosting plan, it is now active.") ) return redirect("billing") if payment.state in (Payment.PENDING, Payment.PROCESSED): messages.info( request, _("Thank you for purchasing a hosting plan, the payment for it is " "pending and will be processed in the background."), ) return redirect("billing") if payment.state == Payment.NEW: return HttpResponseRedirect(payment.get_payment_url()) if payment.state == Payment.REJECTED: messages.error( request, _("The payment was rejected: {}").format( payment.details.get("reject_reason", _("Unknown reason"))), ) return redirect("create-billing")
def post(self, request, **kwargs): component = self.get_component() name = request.POST.get("name") addon = ADDONS.get(name) installed = {x.addon.name for x in self.get_queryset()} if (not name or addon is None or not addon.can_install(component, request.user) or (name in installed and not addon.multiple)): return self.redirect_list(_("Invalid add-on name specified!")) form = None if addon.settings_form is None: addon.create(component) return self.redirect_list() if "form" in request.POST: form = addon.get_add_form(request.user, component, data=request.POST) if form.is_valid(): instance = form.save() if addon.stay_on_create: messages.info( self.request, _("Add-on installed, please review integration instructions." ), ) return redirect(instance) return self.redirect_list() else: form = addon.get_add_form(request.user, component) addon.pre_install(component, request) return self.response_class( request=self.request, template=["addons/addon_detail.html"], context={ "addon": addon, "form": form, "object": self.kwargs["component_obj"], }, )
def trial(request): """Form for hosting request.""" if not settings.OFFER_HOSTING: return redirect("home") plan = request.POST.get("plan", "enterprise") # Avoid frequent requests for a trial for same user if plan != "libre" and request.user.auditlog_set.filter(activity="trial").exists(): messages.error( request, _( "Seems you've already requested a trial period recently. " "Please contact us with your inquiry so we can find the " "best solution for you." ), ) return redirect(reverse("contact") + "?t=trial") if request.method == "POST": from weblate.billing.models import Billing, Plan AuditLog.objects.create(request.user, request, "trial") billing = Billing.objects.create( plan=Plan.objects.get(slug=plan), state=Billing.STATE_TRIAL, expiry=timezone.now() + timedelta(days=14), ) billing.owners.add(request.user) messages.info( request, _( "Your trial period is now up and running; " "create your translation project and start Weblating!" ), ) return redirect(reverse("create-project") + f"?billing={billing.pk}") return render(request, "accounts/trial.html", {"title": _("Gratis trial")})
def perform_translation(unit, form, request): ''' Handles translation and stores it to a backend. ''' # Remember old checks oldchecks = set(unit.active_checks().values_list('check', flat=True)) # Run AutoFixes on user input if not unit.translation.is_template(): new_target, fixups = fix_target(form.cleaned_data['target'], unit) else: new_target = form.cleaned_data['target'] fixups = [] # Save saved = unit.translate(request, new_target, form.cleaned_data['fuzzy']) # Warn about applied fixups if len(fixups) > 0: messages.info( request, _('Following fixups were applied to translation: %s') % ', '.join([force_text(f) for f in fixups])) # Get new set of checks newchecks = set(unit.active_checks().values_list('check', flat=True)) # Did we introduce any new failures? if saved and newchecks > oldchecks: # Show message to user messages.error( request, _('Some checks have failed on your translation: {0}').format( ', '.join( [force_text(CHECKS[check].name) for check in newchecks]))) # Stay on same entry return False return True
def process_view(self, request, view_func, view_args, view_kwargs): """Check request whether user has agreed to TOS.""" # We intercept only GET requests for authenticated users if request.method != 'GET' or not request.user.is_authenticated: return None # Some paths are ignored if self.matcher.match(request.path): return None # Check TOS agreement agreement = Agreement.objects.get_or_create(user=request.user)[0] if not agreement.is_current(): messages.info( request, _('We have new version of the Terms of Service document, ' 'please read it and confirm that you agree with it.')) return redirect('{0}?{1}'.format( reverse('legal:confirm'), urlencode({'next': request.get_full_path()}))) # Explicitly return None for all non-matching requests return None
def perform_suggestion(unit, form, request): ''' Handle suggesion saving. ''' if form.cleaned_data['target'][0] == '': messages.error(request, _('Your suggestion is empty!')) # Stay on same entry return False elif not can_suggest(request.user, unit.translation): # Need privilege to add messages.error( request, _('You don\'t have privileges to add suggestions!') ) # Stay on same entry return False # Invite user to become translator if there is nobody else recent_changes = Change.objects.content(True).filter( translation=unit.translation, ).exclude( user=None ) if not recent_changes.exists(): messages.info(request, _( 'There is currently no active translator for this ' 'translation, please consider becoming a translator ' 'as your suggestion might otherwise remain unreviewed.' )) # Create the suggestion result = Suggestion.objects.add( unit, join_plural(form.cleaned_data['target']), request, ) if not result: messages.error(request, _('Your suggestion already exists!')) return result
def perform_suggestion(unit, form, request): """Handle suggesion saving.""" if form.cleaned_data['target'][0] == '': messages.error(request, _('Your suggestion is empty!')) # Stay on same entry return False elif not can_suggest(request.user, unit.translation): # Need privilege to add messages.error( request, _('You don\'t have privileges to add suggestions!') ) # Stay on same entry return False # Invite user to become translator if there is nobody else recent_changes = Change.objects.content(True).filter( translation=unit.translation, ).exclude( user=None ) if not recent_changes.exists(): messages.info(request, _( 'There is currently no active translator for this ' 'translation, please consider becoming a translator ' 'as your suggestion might otherwise remain unreviewed.' )) # Create the suggestion result = Suggestion.objects.add( unit, join_plural(form.cleaned_data['target']), request, can_vote_suggestion(request.user, unit.translation) ) if not result: messages.error(request, _('Your suggestion already exists!')) return result
def get_next_page(self): messages.info(self.request, _("Thank you for using Weblate.")) return reverse("home")
def translate(request, project, subproject, lang): """Generic entry point for translating, suggesting and searching.""" translation = get_translation(request, project, subproject, lang) # Check locks user_locked = translation.is_user_locked(request.user) project_locked = translation.subproject.locked 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 not 0 <= offset < num_results: messages.info(request, _('You have reached end of translating.')) # Delete search del request.session['search_{0}'.format(search_result['search_id'])] # Redirect to translation return redirect(translation) # Some URLs we will most likely use base_unit_url = '{0}?sid={1}&offset='.format( 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 'accept_edit' 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, next_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 = unit.get_secondary_units(request.user) else: secondary = None # Spam protection antispam = AntispamForm() # Prepare form form = TranslationForm(request.user.profile, translation, unit) others = Unit.objects.same(unit, False) # Is it only this unit? if others.count() == 1: others = Unit.objects.none() return render( request, 'translate.html', { '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, 'project': translation.subproject.project, 'unit': unit, 'others': others, 'others_count': others.exclude(target=unit.target).count(), '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': search_result['form'], 'update_lock': translation.lock_user == request.user, 'secondary': secondary, 'locked': locked, 'user_locked': user_locked, 'project_locked': project_locked, 'glossary': Dictionary.objects.get_words(unit), 'addword_form': InlineWordForm(), })
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 perform_translation(unit, form, request): """Handle translation and stores it to a backend.""" user = request.user profile = user.profile project = unit.translation.component.project # Remember old checks oldchecks = unit.all_checks_names # Save saved = unit.translate(user, form.cleaned_data["target"], form.cleaned_data["state"]) # Warn about applied fixups if unit.fixups: messages.info( request, _("Following fixups were applied to translation: %s") % ", ".join(str(f) for f in unit.fixups), ) # No change edit - should we skip to next entry if not saved: revert_rate_limit("translate", request) return True # Auto subscribe user if not profile.languages.exists(): language = unit.translation.language profile.languages.add(language) messages.info( request, _("Added %(language)s to your translated languages. " "You can adjust them in the settings.") % {"language": language}, ) if profile.auto_watch and not profile.watched.filter( pk=project.pk).exists(): profile.watched.add(project) messages.info( request, _("Added %(project)s to your watched projects. " "You can adjust them and this behavior in the settings.") % {"project": project}, ) # Get new set of checks newchecks = unit.all_checks_names # Did we introduce any new failures? if (saved and form.cleaned_data["state"] >= STATE_TRANSLATED and newchecks > oldchecks): # Show message to user messages.error( request, _("The translation has been saved, however there " "are some newly failing checks: {0}").format(", ".join( str(CHECKS[check].name) for check in newchecks)), ) # Stay on same entry return False return True
def translate(request, project, component, lang): """Generic entry point for translating, suggesting and searching.""" translation = get_translation(request, project, component, lang) # Check locks locked = translation.component.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 offset = search_result["offset"] # Checksum unit access if search_result["checksum"]: try: unit = translation.unit_set.get(id_hash=search_result["checksum"]) offset = search_result["ids"].index(unit.id) + 1 except (Unit.DoesNotExist, ValueError): messages.warning(request, _("No string matched your search!")) return redirect(translation) # 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"]] # Redirect to translation return redirect(translation) # Some URLs we will most likely use base_unit_url = "{0}?{1}&offset=".format(translation.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": 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, translation, 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(translation, request, this_unit_url, next_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 - 1]) except Unit.DoesNotExist: # Can happen when using SID for other translation messages.error(request, _("Invalid search string!")) return redirect(translation) # 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, translation, 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": translation, "project": translation.component.project, "unit": unit, "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( translation, initial={ "scope": "global" if unit.translation.is_source else "translation" }, ), "context_form": ContextForm(instance=unit.source_info, user=request.user), "search_form": search_result["form"].reset_offset(), "secondary": secondary, "locked": locked, "glossary": Dictionary.objects.get_words(unit), "addword_form": InlineWordForm(), "last_changes": unit.change_set.prefetch().order()[:10], "last_changes_url": urlencode(unit.translation.get_reverse_url_kwargs()), }, )
def get_next_page(self): messages.info(self.request, _('Thank you for using Weblate.')) return reverse('home')
def translate(request, project, component, lang): """Generic entry point for translating, suggesting and searching.""" translation = get_translation(request, project, component, lang) # Check locks locked = translation.component.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 offset = search_result['offset'] # Checksum unit access if search_result['checksum']: try: unit = translation.unit_set.get(id_hash=search_result['checksum']) offset = search_result['ids'].index(unit.id) + 1 except (Unit.DoesNotExist, ValueError): messages.warning(request, _('No string matched your search!')) return redirect(translation) # 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']] # Redirect to translation return redirect(translation) # Some URLs we will most likely use base_unit_url = '{0}?{1}&offset='.format( translation.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': 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, translation, 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( translation, request, this_unit_url, next_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 - 1]) 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 = unit.get_secondary_units(request.user) else: secondary = None # Spam protection antispam = AntispamForm() # Prepare form form = TranslationForm(request.user, translation, unit) 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': translation, 'project': translation.component.project, 'unit': unit, 'others': get_other_units(unit), 'total': translation.unit_set.all().count(), 'search_url': search_result['url'], 'search_items': search_result['items'], 'search_query': search_result['query'], 'offset': offset, 'filter_name': search_result['name'], 'filter_count': num_results, 'filter_pos': offset, 'form': form, 'antispam': antispam, 'comment_form': CommentForm(), 'search_form': search_result['form'].reset_offset(), 'secondary': secondary, 'locked': locked, 'glossary': Dictionary.objects.get_words(unit), 'addword_form': InlineWordForm(), } )
def dispatch(self, request, *args, **kwargs): messages.info(self.request, _("Thank you for using Weblate.")) return super().dispatch(request, *args, **kwargs)