text: from django.contrib.auth import update_session_auth_hash
  from django.contrib.auth.forms import PasswordChangeForm
  from django.shortcuts import get_object_or_404
  from django.shortcuts import redirect
  from django.contrib.auth.models import User
  from obywatele.forms import ObywatelForm
  from obywatele.models import Uzytkownik, AkceptacjaOsoby
  from django.shortcuts import render
  from django.contrib import messages
  from django.core.mail import send_mail
  import random
  import string
  from django.utils.timezone import now as dzis
  from math import log
  from django.conf import settings
  from django.contrib.auth.decorators import login_required
  
  
  # Default is 1. Higher limit seams to be problematic
  # bacuse people rarely acctepting each other.
  WYMAGANY_PROCENT_AKCEPTACJI = 1.1
  
  
  @login_required
  def obywatele(request):
      zliczaj_obywateli(request)
      uid = User.objects.filter(is_active=True)
      # TODO: dodać datę przyjęcia do szczegółów każdego użytkownika
      return render(request, 'obywatele/start.html', {'uid': uid})
  
  
  @login_required
  def poczekalnia(request):
      zliczaj_obywateli(request)
      uid = User.objects.filter(is_active=False)
      return render(request, 'obywatele/poczekalnia.html', {'uid': uid})
  
  
  @login_required
  def dodaj(request):
      if request.method == 'POST':
          form = ObywatelForm(request.POST)
          if form.is_valid():
              mail = form.cleaned_data['email']
              nick = form.cleaned_data['username']
  
              if User.objects.filter(email=mail).exists():
                  # is_valid doesn't check if email exist
                  wynik = 'Email już istnieje'
                  return render(request,
                                'obywatele/zapisane.html',
                                {'wynik': wynik, })
  
              else:
                  # If everything is ok
                  form.save()
                  nowa_osoba = User.objects.get(username=nick)
                  nowa_osoba.is_active = False
                  nowy_w_uzytkownikach = Uzytkownik.objects.get(id=nowa_osoba.id)
                  nowy_w_uzytkownikach.polecajacy = request.user.username
                  # nowa_osoba.data_zgloszenia doesn't make sense becauese
                  # date_joined in auth_user already exist.
                  # nowa_osoba.data_zgloszenia nie ma sensu bo już istnieje
                  # date_joined w auth_user
                  nowa_osoba.save()
                  nowy_w_uzytkownikach.save()
  
                  # Since you proposed new person,
                  # you probably also want to accept him/her
                  dawca = Uzytkownik.objects.get(pk=request.user.id)
  
                  glos = AkceptacjaOsoby()
                  nowy_w_uzytkownikach.reputacja += 1
                  glos.kandydat = nowy_w_uzytkownikach
                  glos.obywatel = dawca
                  glos.save()
                  nowy_w_uzytkownikach.save()
  
                  wynik = 'Nowy użytkownik został zapisany'
                  return render(request,
                                'obywatele/zapisane.html',
                                {'wynik': wynik, })
          else:
              wynik = form.errors
              return render(request,
                            'obywatele/zapisane.html',
                            {'wynik': wynik, })
  
      form = ObywatelForm()
      return render(request, 'obywatele/dodaj.html', {'form': form})
  
  
  @login_required
  def obywatele_szczegoly(request, pk):
      dawca = Uzytkownik.objects.get(pk=request.user.id)
      biorca = get_object_or_404(Uzytkownik, pk=pk)
  
      if request.GET.get('tak'):
          # Accept pk
          # Zaakceptuj pk
  
          glos = AkceptacjaOsoby()
  
          # Check if this person already accepted candidate
          # Sprawdźmy czy ten użytkownik polubił już tego kandydata
          jest_glos = AkceptacjaOsoby.objects.filter(obywatel=request.user.id,
                                                     kandydat=pk)
          if jest_glos:
              wynik = 'Już wcześniej nadałeś reputację użytkownikowi ' + str(User.objects.get(pk=pk))
              return render(request,
                            'obywatele/zapisane.html',
                            {'wynik': wynik, })
          else:
              biorca.reputacja += 1
              glos.kandydat = biorca
              glos.obywatel = dawca
              glos.save()
              biorca.save()
              wynik = 'Ok, nadałeś użytkownikowi ' + str(User.objects.get(pk=pk)) + ' punkt reputacji.'
              return render(request,
                            'obywatele/zapisane.html', {'wynik': wynik, })
  
      if request.GET.get('nie'):
          # Recall acceptance from pk
          # Odbierz akceptację od pk
  
          glos = AkceptacjaOsoby()
  
          # Check if this person already accepted candidate
          # Sprawdźmy czy ten użytkownik polubił już tego kandydata
          jest_glos = AkceptacjaOsoby.objects.filter(obywatel=request.user.id,
                                                     kandydat=pk)
  
          if jest_glos:
              glos = AkceptacjaOsoby.objects.filter(obywatel=request.user.id,
                                                    kandydat=pk)
              biorca.reputacja -= 1
  
              AkceptacjaOsoby.objects.get(obywatel=request.user.id,
                                          kandydat=pk).delete()
              biorca.save()
              wynik = f'Ok, odebrałeś użytkownikowi {str(User.objects.get(pk=pk))} punkt reputacji.'
          else:
              wynik = 'Już odebrałeś wcześniej temu użytkownikowi reputację.'
          return render(request, 'obywatele/zapisane.html', {'wynik': wynik, })
  
      populacja = User.objects.filter(is_active=True).count()
      print('populacja:', populacja)
      wymagana_rep = int(log(populacja) * WYMAGANY_PROCENT_AKCEPTACJI)
      twoja_rep = dawca.reputacja
  
      return render(request,
                    'obywatele/szczegoly.html',
                    {'b': biorca,
                     'd': dawca,
                     'tr': twoja_rep,
                     'wr': wymagana_rep})
  
  
  # TODO: zamienić na obiekt z metodą: "podaj obecną populację":
  def zliczaj_obywateli(request):
      '''Citizens should be accepted by voting but banned by
      judge - if they break the law. This is only temporal
      solution for small comunities.'''
      # Potrzebne w 'obywatele_szczegóły'
      populacja = User.objects.filter(is_active=True).count()
      wymagana_reputacja = int(log(populacja) * WYMAGANY_PROCENT_AKCEPTACJI)
  
      akceptacja = AkceptacjaOsoby()
  
      # Blokuj użytkowników ze zbyt niską reputacją
      for i in Uzytkownik.objects.all():
  
          if i.reputacja < wymagana_reputacja and i.uid.is_active:
              i.uid.is_active = False
              i.uid.save()
              i.save()
  
              # Odbierz wszystkim pozostałym 1 punkt reputacji
              for j in Uzytkownik.objects.all():
                  print(j.uid)
                  j.reputacja -= 1
                  j.save()
  
              # Delete this person Acceptance votes
              AkceptacjaOsoby.objects.filter(obywatel=i.id).delete()
  
              send_mail(
                  f'{str(request.get_host())} - Twoje konto zostało zablokowane',
                  f'Witaj {i.uid.username}\nTwoje konto na {str(request.get_host())} zostało zablokowane.',
                  str(settings.DEFAULT_FROM_EMAIL),
                  [i.uid.email],
                  fail_silently=False,
              )
  
              # Also delete this person User and Uzytkownik instances.
              # Uzytkownik.objects.get(id=i.id).delete()
              # User.objects.get(id=i.id).delete()
              # Deleting is bad idea after all. He may come back.
  
      # Włącz użytkowników z odpowiednio wysoką reputacją
      for i in Uzytkownik.objects.all():
          if i.reputacja > wymagana_reputacja and not i.uid.is_active:
              i.uid.is_active = True
              password = password_generator()
              i.uid.set_password(password)
              i.data_przyjecia = dzis()
              i.uid.save()
              i.save()
  
              # Nadaj wszystkim pozostałym 1 punkt reputacji
              for j in Uzytkownik.objects.all():
                  if i != j:
                      j.reputacja += 1
                      j.save()
              
              # Give automatially every person Acceptance
              # New person accepts automatically everyone
              for k in Uzytkownik.objects.all():
                  if i == k:    # but not yourself
                      continue
                  akceptacja = AkceptacjaOsoby()
                  akceptacja.obywatel = i
                  akceptacja.kandydat = k
                  try:
                      akceptacja.save()
                  except:  # TODO: except something
                      continue
  
              subject = request.get_host() + ' - Twoje konto zostało włączone'
              uname = str(i.uid.username)
              uhost = str(request.get_host())
              message = f'Witaj {uname}\nTwoje konto na {uhost} zostało włączone.\n\nTwój login to: {uname}\nTwoje hasło to: {password}\n\nZaloguj się tutaj: {uhost}/login/\n\nHasło możesz zmienić tutaj: {uhost}/haslo/'
  
              send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
                        [i.uid.email], fail_silently=False)
  
  
  def change_password(request):
      if request.method == 'POST':
          form = PasswordChangeForm(request.user, request.POST)
          if form.is_valid():
              user = form.save()
              update_session_auth_hash(request, user)  # Important!
              messages.success(request,
                               'Your password was successfully updated!')
              return redirect('change_password')
          else:
              messages.error(request, 'Please correct the error below.')
      else:
          form = PasswordChangeForm(request.user)
      return render(request, 'obywatele/change_password.html', {'form': form})
  
  
  @login_required
  def profil(request):
      if request.method == 'POST':
          username = request.user.username
          return render(request, 'index.html', {'username': username})
  
  
  def password_generator(size=8, chars=string.ascii_letters + string.digits):
      return ''.join(random.choice(chars) for i in range(size))
  