# Path: core/utils.py
# class UpdateView(BaseUpdateView):
#     template_name_suffix = '_form_update'
# 
# Path: user/decorators.py
# def class_login_required(cls):
#     if (not isinstance(cls, type)
#             or not issubclass(cls, View)):
#         raise ImproperlyConfigured(
#             "class_login_required"
#             " must be applied to subclasses "
#             "of View class.")
#     decorator = method_decorator(login_required)
#     cls.dispatch = decorator(cls.dispatch)
#     return cls
# 
# Path: user/forms.py
# class ResendActivationEmailForm(
#         ActivationMailFormMixin, forms.Form):
# 
#     email = forms.EmailField()
# 
#     mail_validation_error = (
#         'Could not re-send activation email. '
#         'Please try again later. (Sorry!)')
# 
#     def save(self, **kwargs):
#         User = get_user_model()
#         try:
#             user = User.objects.get(
#                 email=self.cleaned_data['email'])
#         except:
#             logger.warning(
#                 'Resend Activation: No user with '
#                 'email: {} .'.format(
#                     self.cleaned_data['email']))
#             return None
#         self.send_mail(user=user, **kwargs)
#         return user
# 
# class UserCreationForm(
#         ActivationMailFormMixin,
#         BaseUserCreationForm):
# 
#     name = forms.CharField(
#         max_length=255,
#         help_text=(
#             "The name displayed on your "
#             "public profile."))
# 
#     mail_validation_error = (
#         'User created. Could not send activation '
#         'email. Please try again later. (Sorry!)')
# 
#     class Meta(BaseUserCreationForm.Meta):
#         model = get_user_model()
#         fields = ('name', 'email')
# 
#     def clean_name(self):
#         name = self.cleaned_data['name']
#         disallowed = (
#             'activate',
#             'create',
#             'disable',
#             'login',
#             'logout',
#             'password',
#             'profile',
#         )
#         if name in disallowed:
#             raise ValidationError(
#                 "A user with that name"
#                 " already exists.")
#         return name
# 
#     def save(self, **kwargs):
#         user = super().save(commit=False)
#         if not user.pk:
#             user.is_active = False
#             send_mail = True
#         else:
#             send_mail = False
#         user.save()
#         self.save_m2m()
#         Profile.objects.update_or_create(
#             user=user,
#             defaults={
#                 'name': self.cleaned_data['name'],
#                 'slug': slugify(
#                     self.cleaned_data['name']),
#             })
#         if send_mail:
#             self.send_mail(user=user, **kwargs)
#         return user
# 
# Path: user/models.py
# class Profile(models.Model):
#     user = models.OneToOneField(
#         settings.AUTH_USER_MODEL)
#     name = models.CharField(
#         max_length=255)
#     slug = models.SlugField(
#         max_length=30,
#         unique=True)
#     about = models.TextField()
#     joined = models.DateTimeField(
#         "Date Joined",
#         auto_now_add=True)
# 
#     objects = ProfileManager()
# 
#     def __str__(self):
#         return self.user.get_username()
# 
#     def get_absolute_url(self):
#         return reverse(
#             'dj-auth:public_profile',
#             kwargs={'slug': self.slug})
# 
#     def get_update_url(self):
#         return reverse('dj-auth:profile_update')
# 
#     def natural_key(self):
#         return (self.slug,)
#     natural_key.dependencies = ['user.user']
# 
# Path: user/utils.py
# class MailContextViewMixin:
#     email_template_name = 'user/email_create.txt'
#     subject_template_name = (
#         'user/subject_create.txt')
# 
#     def get_save_kwargs(self, request):
#         return {
#             'email_template_name':
#                 self.email_template_name,
#             'request': request,
#             'subject_template_name':
#                 self.subject_template_name,
#         }
# 
# class ProfileGetObjectMixin:
# 
#     def get_object(self, queryset=None):
#         current_user = get_user(self.request)
#         return current_user.profile


from django.conf import settings
from django.contrib.auth import (
    get_user, get_user_model, logout)
from django.contrib.auth.decorators import \
    login_required
from django.contrib.auth.tokens import \
    default_token_generator as token_generator
from django.contrib.messages import error, success
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import redirect
from django.template.response import \
    TemplateResponse
from django.utils.decorators import \
    method_decorator
from django.utils.encoding import force_text
from django.utils.http import \
    urlsafe_base64_decode
from django.views.decorators.cache import \
    never_cache
from django.views.decorators.csrf import \
    csrf_protect
from django.views.decorators.debug import \
    sensitive_post_parameters
from django.views.generic import DetailView, View
from core.utils import UpdateView
from .decorators import class_login_required
from .forms import (
    ResendActivationEmailForm, UserCreationForm)
from .models import Profile
from .utils import (
    MailContextViewMixin, ProfileGetObjectMixin)

    @method_decorator(never_cache)
    def get(self, request, uidb64, token):
        User = get_user_model()
        try:
            # urlsafe_base64_decode()
            #     -> bytestring in Py3
            uid = force_text(
                urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except (TypeError, ValueError,
                OverflowError, User.DoesNotExist):
            user = None
        if (user is not None
                and token_generator
                .check_token(user, token)):
            user.is_active = True
            user.save()
            success(
                request,
                'User Activated! '
                'You may now login.')
            return redirect(self.success_url)
        else:
            return TemplateResponse(
                request,
                self.template_name)


class CreateAccount(MailContextViewMixin, View):

# Path: core/utils.py
# class UpdateView(BaseUpdateView):
#     template_name_suffix = '_form_update'
# 
# Path: user/decorators.py
# def class_login_required(cls):
#     if (not isinstance(cls, type)
#             or not issubclass(cls, View)):
#         raise ImproperlyConfigured(
#             "class_login_required"
#             " must be applied to subclasses "
#             "of View class.")
#     decorator = method_decorator(login_required)
#     cls.dispatch = decorator(cls.dispatch)
#     return cls
# 
# Path: user/forms.py
# class ResendActivationEmailForm(
#         ActivationMailFormMixin, forms.Form):
# 
#     email = forms.EmailField()
# 
#     mail_validation_error = (
#         'Could not re-send activation email. '
#         'Please try again later. (Sorry!)')
# 
#     def save(self, **kwargs):
#         User = get_user_model()
#         try:
#             user = User.objects.get(
#                 email=self.cleaned_data['email'])
#         except:
#             logger.warning(
#                 'Resend Activation: No user with '
#                 'email: {} .'.format(
#                     self.cleaned_data['email']))
#             return None
#         self.send_mail(user=user, **kwargs)
#         return user
# 
# class UserCreationForm(
#         ActivationMailFormMixin,
#         BaseUserCreationForm):
# 
#     name = forms.CharField(
#         max_length=255,
#         help_text=(
#             "The name displayed on your "
#             "public profile."))
# 
#     mail_validation_error = (
#         'User created. Could not send activation '
#         'email. Please try again later. (Sorry!)')
# 
#     class Meta(BaseUserCreationForm.Meta):
#         model = get_user_model()
#         fields = ('name', 'email')
# 
#     def clean_name(self):
#         name = self.cleaned_data['name']
#         disallowed = (
#             'activate',
#             'create',
#             'disable',
#             'login',
#             'logout',
#             'password',
#             'profile',
#         )
#         if name in disallowed:
#             raise ValidationError(
#                 "A user with that name"
#                 " already exists.")
#         return name
# 
#     def save(self, **kwargs):
#         user = super().save(commit=False)
#         if not user.pk:
#             user.is_active = False
#             send_mail = True
#         else:
#             send_mail = False
#         user.save()
#         self.save_m2m()
#         Profile.objects.update_or_create(
#             user=user,
#             defaults={
#                 'name': self.cleaned_data['name'],
#                 'slug': slugify(
#                     self.cleaned_data['name']),
#             })
#         if send_mail:
#             self.send_mail(user=user, **kwargs)
#         return user
# 
# Path: user/models.py
# class Profile(models.Model):
#     user = models.OneToOneField(
#         settings.AUTH_USER_MODEL)
#     name = models.CharField(
#         max_length=255)
#     slug = models.SlugField(
#         max_length=30,
#         unique=True)
#     about = models.TextField()
#     joined = models.DateTimeField(
#         "Date Joined",
#         auto_now_add=True)
# 
#     objects = ProfileManager()
# 
#     def __str__(self):
#         return self.user.get_username()
# 
#     def get_absolute_url(self):
#         return reverse(
#             'dj-auth:public_profile',
#             kwargs={'slug': self.slug})
# 
#     def get_update_url(self):
#         return reverse('dj-auth:profile_update')
# 
#     def natural_key(self):
#         return (self.slug,)
#     natural_key.dependencies = ['user.user']
# 
# Path: user/utils.py
# class MailContextViewMixin:
#     email_template_name = 'user/email_create.txt'
#     subject_template_name = (
#         'user/subject_create.txt')
# 
#     def get_save_kwargs(self, request):
#         return {
#             'email_template_name':
#                 self.email_template_name,
#             'request': request,
#             'subject_template_name':
#                 self.subject_template_name,
#         }
# 
# class ProfileGetObjectMixin:
# 
#     def get_object(self, queryset=None):
#         current_user = get_user(self.request)
#         return current_user.profile


# Path: user/views.py
from django.conf import settings
from django.contrib.auth import (
    get_user, get_user_model, logout)
from django.contrib.auth.decorators import \
    login_required
from django.contrib.auth.tokens import \
    default_token_generator as token_generator
from django.contrib.messages import error, success
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import redirect
from django.template.response import \
    TemplateResponse
from django.utils.decorators import \
    method_decorator
from django.utils.encoding import force_text
from django.utils.http import \
    urlsafe_base64_decode
from django.views.decorators.cache import \
    never_cache
from django.views.decorators.csrf import \
    csrf_protect
from django.views.decorators.debug import \
    sensitive_post_parameters
from django.views.generic import DetailView, View
from core.utils import UpdateView
from .decorators import class_login_required
from .forms import (
    ResendActivationEmailForm, UserCreationForm)
from .models import Profile
from .utils import (
    MailContextViewMixin, ProfileGetObjectMixin)


    @method_decorator(never_cache)
    def get(self, request, uidb64, token):
        User = get_user_model()
        try:
            # urlsafe_base64_decode()
            #     -> bytestring in Py3
            uid = force_text(
                urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except (TypeError, ValueError,
                OverflowError, User.DoesNotExist):
            user = None
        if (user is not None
                and token_generator
                .check_token(user, token)):
            user.is_active = True
            user.save()
            success(
                request,
                'User Activated! '
                'You may now login.')
            return redirect(self.success_url)
        else:
            return TemplateResponse(
                request,
                self.template_name)


class CreateAccount(MailContextViewMixin, View):

    form_class = UserCreationForm