def deny_demo(request): """Deny editing of demo account on demo server.""" messages.warning( request, _('You cannot change demo account on the demo server.') ) return redirect_profile(request.POST.get('activetab'))
def adjust_primary_mail(strategy, entries, user, *args, **kwargs): """Fix primary mail on disconnect.""" # Remove pending verification codes mails = VerifiedEmail.objects.filter( social__user=user, social__in=entries ).values_list('email', flat=True) Code.objects.filter(email__in=mails).delete() # Check remaining verified mails verified = VerifiedEmail.objects.filter( social__user=user, ).exclude( social__in=entries ) if verified.filter(email=user.email).exists(): return user.email = verified[0].email user.save() messages.warning( strategy.request, _( 'Your email no longer belongs to verified account, ' 'it has been changed to {0}.' ).format( user.email ) )
def pre_install(cls, component, request): if cls.trigger_update: perform_update.delay('Component', component.pk, auto=True) if component.repo_needs_merge(): messages.warning( request, _('The repository is outdated, you might not get ' 'expected results until you update it.'), )
def search(translation, request, form_class=SearchForm): """Perform search or returns cached search results.""" # Possible new search form = form_class(request.user, request.GET, show_builder=False) # Process form form_valid = form.is_valid() if not form_valid: show_form_errors(request, form) search_result = { "form": form, "offset": form.cleaned_data.get("offset", 1), "checksum": form.cleaned_data.get("checksum"), } search_url = form.urlencode() session_key = "search_{0}_{1}".format(translation.pk, search_url) if ( session_key in request.session and "offset" in request.GET and "items" in request.session[session_key] ): search_result.update(request.session[session_key]) return search_result allunits = translation.unit_set.search(form.cleaned_data.get("q", "")).distinct() search_query = form.get_search_query() if form_valid else "" name = form.get_name() # Grab unit IDs unit_ids = list( allunits.order_by_request(form.cleaned_data).values_list("id", flat=True) ) # Check empty search results if not unit_ids: messages.warning(request, _("No string matched your search!")) return redirect(translation) # Remove old search results cleanup_session(request.session) store_result = { "query": search_query, "url": search_url, "items": form.items(), "key": session_key, "name": force_str(name), "ids": unit_ids, "ttl": int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def deny_demo(request): """ Denies editing of demo account on demo server. """ messages.warning( request, _('You cannot change demo account on the demo server.') ) return redirect_profile(request.POST.get('activetab'))
def add_host_key(request, host, port=""): """Add host key for a host.""" if not host: messages.error(request, _("Invalid host name given!")) else: cmdline = ["ssh-keyscan"] if port: cmdline.extend(["-p", str(port)]) cmdline.append(host) try: result = subprocess.run( cmdline, env=get_clean_env(), check=True, text=True, capture_output=True, ) keys = set() for key in result.stdout.splitlines(): key = key.strip() if not is_key_line(key): continue keys.add(key) host, keytype, fingerprint = parse_hosts_line(key) messages.warning( request, _("Added host key for %(host)s with fingerprint " "%(fingerprint)s (%(keytype)s), " "please verify that it is correct.") % { "host": host, "fingerprint": fingerprint, "keytype": keytype }, ) if keys: known_hosts_file = ssh_file(KNOWN_HOSTS) # Remove existing key entries if os.path.exists(known_hosts_file): with open(known_hosts_file) as handle: for line in handle: keys.discard(line.strip()) # Write any new keys if keys: with open(known_hosts_file, "a") as handle: for key in keys: handle.write(key) handle.write("\n") else: messages.error(request, _("Failed to fetch public key for a host!")) except subprocess.CalledProcessError as exc: messages.error( request, _("Failed to get host key: %s") % exc.stderr or exc.stdout) except OSError as exc: messages.error(request, _("Failed to get host key: %s") % str(exc))
def search(translation, request): """Perform search or returns cached search results.""" # Possible new search form = SearchForm(request.GET) # Process form form_valid = form.is_valid() if not form_valid: show_form_errors(request, form) search_result = { 'form': form, 'offset': form.cleaned_data.get('offset', 1), 'checksum': form.cleaned_data.get('checksum'), } search_url = form.urlencode() session_key = 'search_{0}_{1}'.format(translation.pk, search_url) if (session_key in request.session and 'offset' in request.GET and 'items' in request.session[session_key]): search_result.update(request.session[session_key]) return search_result allunits = translation.unit_set.search( form.cleaned_data, translation=translation, ) search_query = form.get_search_query() if form_valid else '' name = form.get_name() if form_valid else '' # Grab unit IDs unit_ids = list(allunits.order().values_list('id', flat=True)) # Check empty search results if not unit_ids: messages.warning(request, _('No string matched your search!')) return redirect(translation) # Remove old search results cleanup_session(request.session) store_result = { 'query': search_query, 'url': search_url, 'items': form.items(), 'key': session_key, 'name': force_text(name), 'ids': unit_ids, 'ttl': int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def search(translation, request): """Perform search or returns cached search results.""" # Possible new search form = SearchForm(request.GET) # Process form form_valid = form.is_valid() if not form_valid: show_form_errors(request, form) search_result = { 'form': form, 'offset': form.cleaned_data.get('offset', 1), 'checksum': form.cleaned_data.get('checksum'), } search_url = form.urlencode() session_key = 'search_{0}_{1}'.format(translation.pk, search_url) if (session_key in request.session and 'offset' in request.GET and 'items' in request.session[session_key]): search_result.update(request.session[session_key]) return search_result allunits = translation.unit_set.search( form.cleaned_data, translation=translation, ) search_query = form.get_search_query() if form_valid else '' name = form.get_name() if form_valid else '' # Grab unit IDs unit_ids = list(allunits.values_list('id', flat=True)) # Check empty search results if not unit_ids: messages.warning(request, _('No string matched your search!')) return redirect(translation) # Remove old search results cleanup_session(request.session) store_result = { 'query': search_query, 'url': search_url, 'items': form.items(), 'key': session_key, 'name': force_text(name), 'ids': unit_ids, 'ttl': int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def warn_outdated(self, form): linked = form.instance.linked_component if linked: perform_update.delay("Component", linked.pk, auto=True) if linked.repo_needs_merge(): messages.warning( self.request, _("The repository is outdated, you might not get " "expected results until you update it."), )
def add_host_key(request): """Add host key for a host.""" host = request.POST.get('host', '') port = request.POST.get('port', '') if len(host) == 0: messages.error(request, _('Invalid host name given!')) else: cmdline = ['ssh-keyscan'] if port: cmdline.extend(['-p', port]) cmdline.append(host) try: output = subprocess.check_output( cmdline, stderr=subprocess.STDOUT, env=get_clean_env(), ) keys = [] for key in output.decode('utf-8').splitlines(): key = key.strip() if not is_key_line(key): continue keys.append(key) host, keytype, fingerprint = parse_hosts_line(key) messages.warning( request, _( 'Added host key for %(host)s with fingerprint ' '%(fingerprint)s (%(keytype)s), ' 'please verify that it is correct.' ) % { 'host': host, 'fingerprint': fingerprint, 'keytype': keytype, } ) if len(keys) == 0: messages.error( request, _('Failed to fetch public key for a host!') ) with open(ssh_file(KNOWN_HOSTS), 'a') as handle: for key in keys: handle.write('{0}\n'.format(key)) except subprocess.CalledProcessError as exc: messages.error( request, _('Failed to get host key: %s') % exc.output ) except OSError as exc: messages.error( request, _('Failed to get host key: %s') % str(exc) )
def ensure_valid(strategy, backend, user, registering_user, weblate_action, weblate_expires, new_association, details, **kwargs): """Ensure the activation link is still.""" # Didn't the link expire? if weblate_expires < time.time(): raise AuthMissingParameter(backend, 'expires') # We allow password reset for unauthenticated users if weblate_action == 'reset': if strategy.request.user.is_authenticated: messages.warning( strategy.request, _('You can not complete password reset while logged in!'), ) messages.warning(strategy.request, _('The registration link has been invalidated.')) raise AuthMissingParameter(backend, 'user') return # Add e-mail/register should stay on same user if user and user.is_authenticated: current_user = user.pk else: current_user = None if current_user != registering_user: if registering_user is None: messages.warning( strategy.request, _('You can not complete registration while logged in!'), ) else: messages.warning( strategy.request, _('You can confirm your registration only while logged in!'), ) messages.warning(strategy.request, _('The registration link has been invalidated.')) raise AuthMissingParameter(backend, 'user') # Verify if this mail is not used on other accounts if new_association: same = VerifiedEmail.objects.filter(email=details['email']) if user: same = same.exclude(social__user=user) if same.exists(): AuditLog.objects.create(same[0].social.user, strategy.request, 'connect') raise AuthAlreadyAssociated(backend, 'E-mail exists')
def adjust_primary_mail(strategy, entries, user, *args, **kwargs): """Fix primary mail on disconnect.""" verified = VerifiedEmail.objects.filter( social__user=user, ).exclude(social__in=entries) if verified.filter(email=user.email).exists(): return user.email = verified[0].email user.save() messages.warning( strategy.request, _('Your email no longer belongs to verified account, ' 'it has been changed to {0}.').format(user.email))
def add_host_key(request, host, port=""): """Add host key for a host.""" if not host: messages.error(request, _("Invalid host name given!")) else: cmdline = ["ssh-keyscan"] if port: cmdline.extend(["-p", str(port)]) cmdline.append(host) try: result = subprocess.run( cmdline, env=get_clean_env(), check=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) keys = [] for key in result.stdout.splitlines(): key = key.strip() if not is_key_line(key): continue keys.append(key) host, keytype, fingerprint = parse_hosts_line(key) messages.warning( request, _("Added host key for %(host)s with fingerprint " "%(fingerprint)s (%(keytype)s), " "please verify that it is correct.") % { "host": host, "fingerprint": fingerprint, "keytype": keytype }, ) if not keys: messages.error(request, _("Failed to fetch public key for a host!")) with open(ssh_file(KNOWN_HOSTS), "a") as handle: for key in keys: handle.write("{0}\n".format(key)) except subprocess.CalledProcessError as exc: messages.error( request, _("Failed to get host key: %s") % exc.stderr or exc.stdout) except OSError as exc: messages.error(request, _("Failed to get host key: %s") % str(exc))
def adjust_primary_mail(strategy, entries, user, *args, **kwargs): """Fix primary mail on disconnect.""" # Remove pending verification codes invalidate_reset_codes(user=user, entries=entries) # Check remaining verified mails verified = VerifiedEmail.objects.filter(social__user=user).exclude( social__in=entries) if verified.filter(email=user.email).exists(): return user.email = verified[0].email user.save() messages.warning( strategy.request, _('Your e-mail no longer belongs to verified account, ' 'it has been changed to {0}.').format(user.email), )
def adjust_primary_mail(strategy, entries, user, *args, **kwargs): """Fix primary mail on disconnect.""" # Remove pending verification codes mails = VerifiedEmail.objects.filter( social__user=user, social__in=entries).values_list('email', flat=True) Code.objects.filter(email__in=mails).delete() # Check remaining verified mails verified = VerifiedEmail.objects.filter( social__user=user, ).exclude(social__in=entries) if verified.filter(email=user.email).exists(): return user.email = verified[0].email user.save() messages.warning( strategy.request, _('Your email no longer belongs to verified account, ' 'it has been changed to {0}.').format(user.email))
def adjust_primary_mail(strategy, entries, user, *args, **kwargs): """Fix primary mail on disconnect.""" verified = VerifiedEmail.objects.filter( social__user=user, ).exclude( social__in=entries ) if verified.filter(email=user.email).exists(): return user.email = verified[0].email user.save() messages.warning( strategy.request, _( 'Your email no longer belongs to verified account, ' 'it has been changed to {0}.' ).format( user.email ) )
def home(request): """Home page handler serving different views based on user.""" # This is used on Hosted Weblate to handle removed translation projects. # The redirect itself is done in the http server. if 'removed' in request.GET: messages.warning( request, _('The project you were looking for has been removed, ' 'however you are welcome to contribute to other ones.')) if not request.user.is_authenticated: return dashboard_anonymous(request) 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') # Warn about not filled in username (usually caused by migration of # users from older system if not request.user.full_name or not request.user.email: messages.warning( request, mark_safe('<a href="{0}">{1}</a>'.format( reverse('profile') + '#account', escape( _('Please set your full name and email in your profile.'))) )) return dashboard_user(request)
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 ensure_valid(strategy, backend, user, registering_user, weblate_action, weblate_expires, **kwargs): """Ensure the activation link is still.""" # Didn't the link expire? if weblate_expires < time.time(): raise AuthMissingParameter(backend, 'expires') # We allow password reset for unauthenticated users if weblate_action == 'reset': if strategy.request.user.is_authenticated: messages.warning( strategy.request, _('You can not complete password reset while logged in!')) messages.warning(strategy.request, _('The registration link has been invalidated.')) raise AuthMissingParameter(backend, 'user') return # Add email/register should stay on same user if user and user.is_authenticated: current_user = user.pk else: current_user = None if current_user != registering_user: if registering_user is None: messages.warning( strategy.request, _('You can not complete registration while logged in!')) else: messages.warning( strategy.request, _('You can confirm your registration only while logged in!')) messages.warning(strategy.request, _('The registration link has been invalidated.')) raise AuthMissingParameter(backend, 'user')
def hosting(request): """Form for hosting request.""" if not settings.OFFER_HOSTING or request.user.is_demo: if request.user.is_demo: message = _( 'Please log in using your personal account to request hosting.' ) messages.warning(request, message) return redirect('home') if request.method == 'POST': form = HostingForm(request.POST) if form.is_valid(): context = form.cleaned_data context['username'] = request.user.username mail_admins_contact( request, 'Hosting request for %(project)s', HOSTING_TEMPLATE, context, form.cleaned_data['email'], settings.ADMINS_HOSTING, ) return redirect('home') else: initial = get_initial_contact(request) form = HostingForm(initial=initial) return render( request, 'accounts/hosting.html', { 'form': form, 'title': _('Hosting'), } )
def home(request): """Home page handler serving different views based on user.""" user = request.user # This is used on Hosted Weblate to handle removed translation projects. # The redirect itself is done in the http server. if "removed" in request.GET: messages.warning( request, _( "The project you were looking for has been removed, " "however you are welcome to contribute to other ones." ), ) 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 sign in next time." ), ) return redirect("password") # Warn about not filled in username (usually caused by migration of # users from older system if user.is_authenticated and (not user.full_name or not user.email): messages.warning( request, mark_safe( '<a href="{0}">{1}</a>'.format( reverse("profile") + "#account", escape(_("Please set your full name and e-mail in your profile.")), ) ), ) # Redirect to single project or component if isinstance(settings.SINGLE_PROJECT, str): return redirect(Project.objects.get(slug=settings.SINGLE_PROJECT)) if settings.SINGLE_PROJECT: if Component.objects.count() == 1: return redirect(Component.objects.first()) if Project.objects.count() == 1: return redirect(Project.objects.first()) if not user.is_authenticated: return dashboard_anonymous(request) return dashboard_user(request)
def home(request): """Home page handler serving different views based on user.""" # This is used on Hosted Weblate to handle removed translation projects. # The redirect itself is done in the http server. if 'removed' in request.GET: messages.warning( request, _( 'The project you were looking for has been removed, ' 'however you are welcome to contribute to other ones.' ) ) if not request.user.is_authenticated: return dashboard_anonymous(request) 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') # Warn about not filled in username (usually caused by migration of # users from older system if not request.user.full_name or not request.user.email: messages.warning( request, mark_safe('<a href="{0}">{1}</a>'.format( reverse('profile') + '#account', escape( _('Please set your full name and email in your profile.') ) )) ) return dashboard_user(request)
def user_profile(request): profile = request.user.profile if not request.user.is_demo and not profile.language: profile.language = get_language() profile.save(update_fields=['language']) form_classes = [ ProfileForm, SubscriptionForm, SubscriptionSettingsForm, UserSettingsForm, DashboardSettingsForm, ] all_backends = set(load_backends(social_django.utils.BACKENDS).keys()) if request.method == 'POST': # Parse POST params forms = [form(request.POST, instance=profile) for form in form_classes] forms.append(UserForm(request.POST, instance=request.user)) if request.user.is_demo: return deny_demo(request) if all(form.is_valid() for form in forms): # Save changes for form in forms: form.save() # Change language set_lang(request, request.user.profile) # Redirect after saving (and possibly changing language) response = redirect_profile(request.POST.get('activetab')) # Set language cookie and activate new language (for message below) lang_code = profile.language response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code) translation.activate(lang_code) messages.success(request, _('Your profile has been updated.')) return response else: forms = [form(instance=profile) for form in form_classes] forms.append(UserForm(instance=request.user)) if not request.user.has_usable_password() and 'email' in all_backends: messages.warning( request, render_to_string('accounts/password-warning.html') ) social = request.user.social_auth.all() social_names = [assoc.provider for assoc in social] new_backends = [ x for x in all_backends if x == 'email' or x not in social_names ] license_projects = Component.objects.filter( project__in=request.user.allowed_projects ).exclude( license='' ) result = render( request, 'accounts/profile.html', { 'languagesform': forms[0], 'subscriptionform': forms[1], 'subscriptionsettingsform': forms[2], 'usersettingsform': forms[3], 'dashboardsettingsform': forms[4], 'userform': forms[5], 'profile': profile, 'title': _('User profile'), 'licenses': license_projects, 'associated': social, 'new_backends': new_backends, 'managed_projects': request.user.owned_projects, 'auditlog': request.user.auditlog_set.all()[:20], } ) result.set_cookie( settings.LANGUAGE_COOKIE_NAME, profile.language ) return result
def search(translation, request): """Perform search or returns cached search results.""" # Possible new search search_form = SearchForm(request.GET) review_form = ReviewForm(request.GET) # Process form if 'date' in request.GET: if review_form.is_valid(): form = review_form else: show_form_errors(request, review_form) # Use blank form form = SearchForm([]) form.is_valid() elif search_form.is_valid(): form = search_form else: show_form_errors(request, search_form) # Use blank form form = SearchForm([]) form.is_valid() search_result = { 'form': form, 'offset': form.cleaned_data['offset'], 'checksum': form.cleaned_data['checksum'], } search_url = form.urlencode() session_key = 'search_{0}_{1}'.format(translation.pk, search_url) if session_key in request.session: search_result.update(request.session[session_key]) return search_result if form.cleaned_data['type'] == 'review': allunits = translation.unit_set.review( form.cleaned_data['date'], request.user ) else: allunits = translation.unit_set.search( translation, form.cleaned_data, ) if form.cleaned_data['type'] == 'random': allunits = allunits[:25] search_query = form.get_search_query() name = form.get_name() # 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) # Remove old search results cleanup_session(request.session) store_result = { 'query': search_query, 'url': search_url, 'key': session_key, 'name': force_text(name), 'ids': unit_ids, 'ttl': int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def upload_translation(request, project, subproject, lang): ''' Handling of translation uploads. ''' obj = get_translation(request, project, subproject, lang) if not can_upload_translation(request.user, obj): raise PermissionDenied() # Check method and lock if obj.is_locked(request.user): messages.error(request, _('Access denied.')) return redirect(obj) # Get correct form handler based on permissions form = get_upload_form( request.user, obj, request.POST, request.FILES ) # Check form validity if not form.is_valid(): messages.error(request, _('Please fix errors in the form.')) show_form_errors(request, form) return redirect(obj) # Create author name author = None if (can_author_translation(request.user, obj.subproject.project) and form.cleaned_data['author_name'] != '' and form.cleaned_data['author_email'] != ''): author = '%s <%s>' % ( form.cleaned_data['author_name'], form.cleaned_data['author_email'] ) # Check for overwriting overwrite = False if can_overwrite_translation(request.user, obj.subproject.project): overwrite = form.cleaned_data['overwrite'] # Do actual import try: ret, count = obj.merge_upload( request, request.FILES['file'], overwrite, author, merge_header=form.cleaned_data['merge_header'], merge_comments=form.cleaned_data['merge_comments'], method=form.cleaned_data['method'], fuzzy=form.cleaned_data['fuzzy'], ) import_message( request, count, _('No strings were imported from the uploaded file.'), ungettext( 'Processed %d string from the uploaded files.', 'Processed %d strings from the uploaded files.', count ) ) if not ret: messages.warning( request, _('There were no new strings in uploaded file!') ) except Exception as error: messages.error( request, _('File content merge failed: %s') % force_text(error) ) report_error(error, sys.exc_info(), request) return redirect(obj)
def ensure_valid(strategy, backend, user, registering_user, weblate_action, weblate_expires, new_association, details, **kwargs): """Ensure the activation link is still.""" # Didn't the link expire? if weblate_expires < time.time(): raise AuthMissingParameter(backend, 'expires') # We allow password reset for unauthenticated users if weblate_action == 'reset': if strategy.request.user.is_authenticated: messages.warning( strategy.request, _('You can not complete password reset while logged in!') ) messages.warning( strategy.request, _('The registration link has been invalidated.') ) raise AuthMissingParameter(backend, 'user') return # Add email/register should stay on same user if user and user.is_authenticated: current_user = user.pk else: current_user = None if current_user != registering_user: if registering_user is None: messages.warning( strategy.request, _('You can not complete registration while logged in!') ) else: messages.warning( strategy.request, _('You can confirm your registration only while logged in!') ) messages.warning( strategy.request, _('The registration link has been invalidated.') ) raise AuthMissingParameter(backend, 'user') # Verify if this mail is not used on other accounts if new_association: same = VerifiedEmail.objects.filter( email=details['email'] ) if user: same = same.exclude(social__user=user) if same.exists(): notify_account_activity( same[0].social.user, strategy.request, 'connect' ) raise AuthAlreadyAssociated(backend, 'Email exists')
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 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 import_message(request, count, message_none, message_ok): if count == 0: messages.warning(request, message_none) else: messages.success(request, message_ok % count)
def user_profile(request): profile = request.user.profile if not profile.language: profile.language = get_language() profile.save(update_fields=["language"]) form_classes = [ ProfileForm, SubscriptionForm, UserSettingsForm, DashboardSettingsForm, UserForm, ] forms = [form.from_request(request) for form in form_classes] forms.extend(get_notification_forms(request)) all_backends = get_auth_keys() if request.method == "POST": if all(form.is_valid() for form in forms): # Save changes for form in forms: if hasattr(form, "audit"): form.audit(request) form.save() messages.success(request, _("Your profile has been updated.")) # Redirect after saving (and possibly changing language) return redirect_profile(request.POST.get("activetab")) else: if not request.user.has_usable_password() and "email" in all_backends: messages.warning( request, render_to_string("accounts/password-warning.html")) social = request.user.social_auth.all() social_names = [assoc.provider for assoc in social] new_backends = [ x for x in sorted(all_backends) if x == "email" or x not in social_names ] license_projects = (Component.objects.filter_access( request.user).exclude(license="").prefetch().order_by("license")) result = render( request, "accounts/profile.html", { "languagesform": forms[0], "subscriptionform": forms[1], "usersettingsform": forms[2], "dashboardsettingsform": forms[3], "userform": forms[4], "notification_forms": forms[5:], "all_forms": forms, "profile": profile, "title": _("User profile"), "licenses": license_projects, "associated": social, "new_backends": new_backends, "has_email_auth": "email" in all_backends, "auditlog": request.user.auditlog_set.order()[:20], }, ) return result
def user_profile(request): profile = request.user.profile if not request.user.is_demo and not profile.language: profile.language = get_language() profile.save(update_fields=['language']) form_classes = [ ProfileForm, SubscriptionForm, SubscriptionSettingsForm, UserSettingsForm, DashboardSettingsForm, ] all_backends = set(load_backends(social_django.utils.BACKENDS).keys()) if request.method == 'POST': # Parse POST params forms = [form(request.POST, instance=profile) for form in form_classes] forms.append(UserForm(request.POST, instance=request.user)) if request.user.is_demo: return deny_demo(request) if all(form.is_valid() for form in forms): # Save changes for form in forms: form.save() # Change language set_lang(request, request.user.profile) # Redirect after saving (and possibly changing language) response = redirect_profile(request.POST.get('activetab')) # Set language cookie and activate new language (for message below) lang_code = profile.language response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code) translation.activate(lang_code) messages.success(request, _('Your profile has been updated.')) return response else: forms = [form(instance=profile) for form in form_classes] forms.append(UserForm(instance=request.user)) if not request.user.has_usable_password() and 'email' in all_backends: messages.warning( request, render_to_string('accounts/password-warning.html')) social = request.user.social_auth.all() social_names = [assoc.provider for assoc in social] new_backends = [ x for x in all_backends if x == 'email' or x not in social_names ] license_projects = Component.objects.filter( project__in=request.user.allowed_projects).exclude(license='') billings = None if 'weblate.billing' in settings.INSTALLED_APPS: # pylint: disable=wrong-import-position from weblate.billing.models import Billing billings = Billing.objects.filter( projects__in=request.user.projects_with_perm( 'billing.view')).distinct() result = render( request, 'accounts/profile.html', { 'form': forms[0], 'subscriptionform': forms[1], 'subscriptionsettingsform': forms[2], 'usersettingsform': forms[3], 'dashboardsettingsform': forms[4], 'userform': forms[5], 'profile': profile, 'title': _('User profile'), 'licenses': license_projects, 'associated': social, 'new_backends': new_backends, 'managed_projects': request.user.owned_projects, 'auditlog': request.user.auditlog_set.all()[:20], 'billings': billings, }) result.set_cookie(settings.LANGUAGE_COOKIE_NAME, profile.language) return result
def search(translation, request): """Perform search or returns cached search results.""" # Already performed search if 'sid' in request.GET: # Grab from session storage search_id = 'search_{0}'.format(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) search_result = copy.copy(request.session[search_id]) if 'params' in search_result: search_result['form'] = SearchForm(search_result['params']) else: search_result['form'] = SearchForm() return search_result # Possible new search search_form = SearchForm(request.GET) review_form = ReviewForm(request.GET) search_query = None if 'date' in request.GET: 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 else: show_form_errors(request, review_form) # Filtering by type allunits = translation.unit_set.all() name = _('All strings') elif search_form.is_valid(): # Apply search conditions allunits = translation.unit_set.search( translation, search_form.cleaned_data, ) search_query = search_form.cleaned_data['q'] name = search_form.get_name() else: # Error reporting show_form_errors(request, search_form) # Filtering by type allunits = translation.unit_set.all() name = _('All strings') # 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( id_hash=checksum_to_hash(request.GET['checksum']))[0] offset = unit_ids.index(unit.id) except (Unit.DoesNotExist, IndexError, ValueError): 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 = { 'params': request.GET, 'query': search_query, 'name': force_text(name), 'ids': unit_ids, 'search_id': search_id, 'ttl': int(time.time()) + 86400, 'offset': offset, } request.session['search_{0}'.format(search_id)] = search_result search_result = copy.copy(search_result) search_result['form'] = search_form return search_result
def upload_translation(request, project, component, lang): """Handling of translation uploads.""" obj = get_translation(request, project, component, lang) if not request.user.has_perm('upload.perform', obj): raise PermissionDenied() # Check method and lock if obj.component.locked: messages.error(request, _('Access denied.')) return redirect(obj) # Get correct form handler based on permissions form = get_upload_form(request.user, obj, request.POST, request.FILES) # Check form validity if not form.is_valid(): messages.error(request, _('Please fix errors in the form.')) show_form_errors(request, form) return redirect(obj) # Create author name author_name = None author_email = None if request.user.has_perm('upload.authorship', obj): author_name = form.cleaned_data['author_name'] author_email = form.cleaned_data['author_email'] # Check for overwriting overwrite = False if request.user.has_perm('upload.overwrite', obj): overwrite = form.cleaned_data['upload_overwrite'] # Do actual import try: not_found, skipped, accepted, total = obj.merge_upload( request, request.FILES['file'], overwrite, author_name, author_email, method=form.cleaned_data['method'], fuzzy=form.cleaned_data['fuzzy'], ) if total == 0: message = _('No strings were imported from the uploaded file.') else: message = ungettext( 'Processed {0} string from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', 'Processed {0} strings from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', total).format(total, skipped, not_found, accepted) if accepted == 0: messages.warning(request, message) else: messages.success(request, message) except Exception as error: messages.error(request, _('File content merge failed: %s') % force_text(error)) report_error(error, request, prefix='Failed to merge content') return redirect(obj)
def user_profile(request): profile = request.user.profile if not profile.language: profile.language = get_language() profile.save() form_classes = [ ProfileForm, SubscriptionForm, SubscriptionSettingsForm, UserSettingsForm, DashboardSettingsForm, ] all_backends = set(load_backends(BACKENDS).keys()) if request.method == 'POST': # Parse POST params forms = [form(request.POST, instance=profile) for form in form_classes] forms.append(UserForm(request.POST, instance=request.user)) if settings.DEMO_SERVER and request.user.username == 'demo': return deny_demo(request) if all(form.is_valid() for form in forms): # Save changes for form in forms: form.save() # Change language set_lang(request, request.user.profile) # Redirect after saving (and possibly changing language) response = redirect_profile(request.POST.get('activetab')) # Set language cookie and activate new language (for message below) lang_code = profile.language response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code) translation.activate(lang_code) messages.success(request, _('Your profile has been updated.')) return response else: forms = [form(instance=profile) for form in form_classes] forms.append(UserForm(instance=request.user)) if not request.user.has_usable_password() and 'email' in all_backends: messages.warning( request, render_to_string('accounts/password-warning.html') ) social = request.user.social_auth.all() social_names = [assoc.provider for assoc in social] new_backends = [ x for x in all_backends if x == 'email' or x not in social_names ] license_projects = SubProject.objects.filter( project__in=Project.objects.all_acl(request.user) ).exclude( license='' ) result = render( request, 'accounts/profile.html', { 'form': forms[0], 'subscriptionform': forms[1], 'subscriptionsettingsform': forms[2], 'usersettingsform': forms[3], 'dashboardsettingsform': forms[4], 'userform': forms[5], 'profile': profile, 'title': _('User profile'), 'licenses': license_projects, 'associated': social, 'new_backends': new_backends, 'managed_projects': Project.objects.filter( groupacl__groups__name__endswith='@Administration', groupacl__groups__user=request.user, ).distinct(), 'auditlog': request.user.auditlog_set.all()[:20], } ) result.set_cookie( settings.LANGUAGE_COOKIE_NAME, profile.language ) return result
def upload_translation(request, project, component, lang): """Handling of translation uploads.""" obj = get_translation(request, project, component, lang) if not request.user.has_perm('upload.perform', obj): raise PermissionDenied() # Check method and lock if obj.component.locked: messages.error(request, _('Access denied.')) return redirect(obj) # Get correct form handler based on permissions form = get_upload_form( request.user, obj, request.POST, request.FILES ) # Check form validity if not form.is_valid(): messages.error(request, _('Please fix errors in the form.')) show_form_errors(request, form) return redirect(obj) # Create author name author = None if (request.user.has_perm('upload.authorship', obj) and form.cleaned_data['author_name'] != '' and form.cleaned_data['author_email'] != ''): author = '{0} <{1}>'.format( form.cleaned_data['author_name'], form.cleaned_data['author_email'] ) # Check for overwriting overwrite = False if request.user.has_perm('upload.overwrite', obj): overwrite = form.cleaned_data['upload_overwrite'] # Do actual import try: not_found, skipped, accepted, total = obj.merge_upload( request, request.FILES['file'], overwrite, author, merge_header=form.cleaned_data['merge_header'], method=form.cleaned_data['method'], fuzzy=form.cleaned_data['fuzzy'], ) if total == 0: message = _('No strings were imported from the uploaded file.') else: message = ungettext( 'Processed {0} string from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', 'Processed {0} strings from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', total ).format(total, skipped, not_found, accepted) if accepted == 0: messages.warning(request, message) else: messages.success(request, message) except Exception as error: messages.error( request, _('File content merge failed: %s') % force_text(error) ) report_error(error, sys.exc_info(), request) return redirect(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') # This is used on Hosted Weblate to handle removed translation projects. # The redirect itself is done in the http server. if 'removed' in request.GET: messages.warning( request, _( 'The project you were looking for has been removed, ' 'however you are welcome to contribute to other ones.' ) ) user = request.user user_translations = get_user_translations(request, user) suggestions = get_suggestions(request, user, user_translations) # Warn about not filled in username (usually caused by migration of # users from older system if user.is_authenticated and user.full_name == '': messages.warning( request, mark_safe('<a href="{0}">{1}</a>'.format( reverse('profile') + '#account', escape(_('Please set your full name in your profile.')) )) ) usersubscriptions = None componentlists = list(ComponentList.objects.filter(show_dashboard=True)) for componentlist in componentlists: componentlist.translations = prefetch_stats( user_translations.filter( component__in=componentlist.components.all() ) ) # Filter out component lists with translations # This will remove the ones where user doesn't have access to anything componentlists = [c for c in componentlists if c.translations] active_tab_id = user.profile.dashboard_view active_tab_slug = Profile.DASHBOARD_SLUGS.get(active_tab_id) if active_tab_id == Profile.DASHBOARD_COMPONENT_LIST: active_tab_slug = user.profile.dashboard_component_list.tab_slug() if user.is_authenticated: # Ensure ACL filtering applies (user could have been removed # from the project meanwhile) subscribed_projects = user.allowed_projects.filter( profile=user.profile ) usersubscriptions = user_translations.filter( component__project__in=subscribed_projects ) if user.profile.hide_completed: usersubscriptions = get_untranslated(usersubscriptions) user_translations = get_untranslated(user_translations) for componentlist in componentlists: componentlist.translations = get_untranslated( componentlist.translations ) usersubscriptions = prefetch_stats(usersubscriptions) return render( request, 'index.html', { 'allow_index': True, 'suggestions': suggestions, 'search_form': SiteSearchForm(), 'usersubscriptions': usersubscriptions, 'userlanguages': prefetch_stats(user_translations), 'componentlists': componentlists, 'all_componentlists': prefetch_stats(ComponentList.objects.all()), 'active_tab_slug': active_tab_slug, } )
def search(base, unit_set, request): """Perform search or returns cached search results.""" # Possible new search form = PositionSearchForm(user=request.user, data=request.GET, show_builder=False) # Process form form_valid = form.is_valid() if form_valid: cleaned_data = form.cleaned_data search_url = form.urlencode() search_query = form.get_search_query() name = form.get_name() search_items = form.items() else: cleaned_data = {} show_form_errors(request, form) search_url = "" search_query = "" name = "" search_items = () search_result = { "form": form, "offset": cleaned_data.get("offset", 1), } session_key = f"search_{base.cache_key}_{search_url}" if (session_key in request.session and "offset" in request.GET and "items" in request.session[session_key]): search_result.update(request.session[session_key]) return search_result allunits = unit_set.search(cleaned_data.get("q", "")).distinct() # Grab unit IDs unit_ids = list( allunits.order_by_request(cleaned_data).values_list("id", flat=True)) # Check empty search results if not unit_ids: messages.warning(request, _("No string matched your search!")) return redirect(base) # Remove old search results cleanup_session(request.session) store_result = { "query": search_query, "url": search_url, "items": search_items, "key": session_key, "name": str(name), "ids": unit_ids, "ttl": int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def search(translation, request): """Perform search or returns cached search results.""" # Possible new search search_form = SearchForm(request.GET) review_form = ReviewForm(request.GET) # Process form if 'date' in request.GET: if review_form.is_valid(): form = review_form else: show_form_errors(request, review_form) # Use blank form form = SearchForm([]) form.is_valid() elif search_form.is_valid(): form = search_form else: show_form_errors(request, search_form) # Use blank form form = SearchForm([]) form.is_valid() search_result = { 'form': form, 'offset': form.cleaned_data['offset'], 'checksum': form.cleaned_data['checksum'], } search_url = form.urlencode() session_key = 'search_{0}_{1}'.format(translation.pk, search_url) if session_key in request.session and 'offset' in request.GET: search_result.update(request.session[session_key]) return search_result if form.cleaned_data['type'] == 'review': allunits = translation.unit_set.review(form.cleaned_data['date'], request.user) else: allunits = translation.unit_set.search( translation, form.cleaned_data, ) if form.cleaned_data['type'] == 'random': allunits = allunits[:25] search_query = form.get_search_query() name = form.get_name() # 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) # Remove old search results cleanup_session(request.session) store_result = { 'query': search_query, 'url': search_url, 'key': session_key, 'name': force_text(name), 'ids': unit_ids, 'ttl': int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def upload_translation(request, project, component, lang): """Handling of translation uploads.""" obj = get_translation(request, project, component, lang) if not request.user.has_perm("upload.perform", obj): raise PermissionDenied() # Check method and lock if obj.component.locked: messages.error(request, _("Access denied.")) return redirect(obj) # Get correct form handler based on permissions form = get_upload_form(request.user, obj, request.POST, request.FILES) # Check form validity if not form.is_valid(): messages.error(request, _("Please fix errors in the form.")) show_form_errors(request, form) return redirect(obj) # Create author name author_name = None author_email = None if request.user.has_perm("upload.authorship", obj): author_name = form.cleaned_data["author_name"] author_email = form.cleaned_data["author_email"] # Check for overwriting conflicts = "" if request.user.has_perm("upload.overwrite", obj): conflicts = form.cleaned_data["conflicts"] # Do actual import try: not_found, skipped, accepted, total = obj.handle_upload( request, request.FILES["file"], conflicts, author_name, author_email, method=form.cleaned_data["method"], fuzzy=form.cleaned_data["fuzzy"], ) if total == 0: message = _("No strings were imported from the uploaded file.") else: message = ngettext( "Processed {0} string from the uploaded files " "(skipped: {1}, not found: {2}, updated: {3}).", "Processed {0} strings from the uploaded files " "(skipped: {1}, not found: {2}, updated: {3}).", total, ).format(total, skipped, not_found, accepted) if accepted == 0: messages.warning(request, message) else: messages.success(request, message) except PluralFormsMismatch: messages.error( request, _("Plural forms in the uploaded file do not match current translation." ), ) except Exception as error: messages.error( request, _("File upload has failed: %s") % str(error).replace(obj.component.full_path, ""), ) report_error(cause="Upload error") return redirect(obj)
def user_profile(request): profile = request.user.profile if not profile.language: profile.language = get_language() profile.save(update_fields=['language']) form_classes = [ ProfileForm, SubscriptionForm, UserSettingsForm, DashboardSettingsForm, UserForm, ] forms = [form.from_request(request) for form in form_classes] forms.extend(get_notification_forms(request)) all_backends = set(load_backends(social_django.utils.BACKENDS).keys()) if request.method == 'POST': if all(form.is_valid() for form in forms): # Save changes for form in forms: if hasattr(form, 'audit'): form.audit(request) form.save() # Change language set_lang(request, request.user.profile) # Redirect after saving (and possibly changing language) response = redirect_profile(request.POST.get('activetab')) # Set language cookie and activate new language (for message below) lang_code = profile.language response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code) translation.activate(lang_code) messages.success(request, _('Your profile has been updated.')) return response else: if not request.user.has_usable_password() and 'email' in all_backends: messages.warning( request, render_to_string('accounts/password-warning.html')) social = request.user.social_auth.all() social_names = [assoc.provider for assoc in social] new_backends = [ x for x in all_backends if x == 'email' or x not in social_names ] license_projects = (Component.objects.filter( project__in=request.user.allowed_projects).exclude( license='').prefetch().order_by('license')) result = render( request, 'accounts/profile.html', { 'languagesform': forms[0], 'subscriptionform': forms[1], 'usersettingsform': forms[2], 'dashboardsettingsform': forms[3], 'userform': forms[4], 'notification_forms': forms[5:], 'all_forms': forms, 'profile': profile, 'title': _('User profile'), 'licenses': license_projects, 'associated': social, 'new_backends': new_backends, 'auditlog': request.user.auditlog_set.order()[:20], }, ) result.set_cookie(settings.LANGUAGE_COOKIE_NAME, profile.language) return result
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') user = request.user project_ids = Project.objects.get_acl_ids(user) translations_base = get_user_translations(user, project_ids) suggestions = get_suggestions(request, user, translations_base) # Warn about not filled in username (usually caused by migration of # users from older system if not user.is_anonymous and user.first_name == '': messages.warning( request, _('Please set your full name in your profile.') ) # Some stats last_changes = Change.objects.last_changes(user) # dashboard_choices is dict with labels of choices as a keys dashboard_choices = dict(Profile.DASHBOARD_CHOICES) usersubscriptions = None components_by_language = translations_base.order_by( 'subproject__priority', 'subproject__project__name', 'subproject__name' ) userlanguages = components_by_language.filter( subproject__project_id__in=project_ids ) componentlists = list(ComponentList.objects.all()) for componentlist in componentlists: componentlist.translations = components_by_language.filter( subproject__in=componentlist.components.all() ) active_tab_id = user.profile.dashboard_view active_tab_slug = Profile.DASHBOARD_SLUGS.get(active_tab_id) if active_tab_id == Profile.DASHBOARD_COMPONENT_LIST: clist = user.profile.dashboard_component_list active_tab_slug = clist.tab_slug() dashboard_choices[active_tab_id] = clist.name if request.user.is_authenticated: # Ensure ACL filtering applies (user could have been removed # from the project meanwhile) subscribed_projects = user.profile.subscriptions.filter( id__in=project_ids ) last_changes = last_changes.filter( subproject__project__in=subscribed_projects ) usersubscriptions = components_by_language.filter( subproject__project__in=subscribed_projects ) return render( request, 'index.html', { 'allow_index': True, 'suggestions': suggestions, 'last_changes': last_changes[:10], 'last_changes_url': '', 'search_form': SiteSearchForm(), 'usersubscriptions': usersubscriptions, 'userlanguages': userlanguages, 'componentlists': componentlists, 'active_tab_slug': active_tab_slug, 'active_tab_label': dashboard_choices.get(active_tab_id) } )