You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

156 lines
6.0 KiB

from io import BytesIO
from PIL import Image
from os.path import splitext
from datetime import timedelta
from django.contrib.auth import login
from django.core.exceptions import ValidationError
from django.shortcuts import render, reverse, redirect
from django.views.generic import DetailView, UpdateView, TemplateView, FormView
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.hashers import check_password, make_password
from django.http import Http404
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.utils.timezone import now
from apps.auth.tokens import verification_email_token
from apps.course.models import Course
from apps.payment.models import AuthorBalance, CoursePayment
from apps.notification.utils import send_email
from .forms import UserEditForm, WithdrawalForm
User = get_user_model()
@login_required
def resend_email_verify(request):
token = verification_email_token.make_token(request.user)
url = request.scheme + '://' + request.get_host() + str(reverse_lazy('lilcity:verification-email', args=[token]))
send_email('Verification Email', request.user.email, "notification/email/verification_email.html", url=url)
messages.info(request, 'Письмо подтверждения отправлено.')
return redirect('user-edit-profile', request.user.id)
@method_decorator(login_required, name='dispatch')
class UserView(DetailView):
model = User
template_name = 'user/profile.html'
def get_context_data(self, object):
context = super().get_context_data()
context['published'] = Course.objects.filter(
author=self.object,
)
context['pending'] = Course.objects.filter(
author=self.object, status=Course.PENDING
)
context['drafts'] = Course.objects.filter(
author=self.object, status=Course.DRAFT
)
context['paid'] = Course.objects.filter(
payments__in=CoursePayment.objects.filter(user=self.object),
).distinct()
return context
@method_decorator(login_required, name='dispatch')
class NotificationEditView(TemplateView):
template_name = 'user/notification-settings.html'
def get(self, request, pk=None):
return super().get(request)
@method_decorator(login_required, name='dispatch')
class PaymentHistoryView(FormView):
template_name = 'user/payment-history.html'
form_class = WithdrawalForm
def get(self, request, pk=None):
return super().get(request)
def post(self, request, pk=None):
form = self.get_form()
if AuthorBalance.objects.filter(created_at__gte=now() - timedelta(days=30)).exists():
messages.error(request, 'Запрос на вывод средств можно сделать только один раз в 30 дней.')
return self.form_invalid(form)
if form.is_valid():
if request.user.balance < form.cleaned_data['amount']:
form.errors['amount'] = 'Сумма для вывода не может быть меньше средств на счету'
return self.form_invalid(form)
AuthorBalance.objects.create(
author=request.user,
type=AuthorBalance.OUT,
amount=form.cleaned_data['amount'],
status=AuthorBalance.PENDING,
card=form.cleaned_data['amount'],
)
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_success_url(self):
success_url = reverse_lazy('user-edit-payments', args=[self.request.user.id])
return success_url
@method_decorator(login_required, name='dispatch')
class UserEditView(UpdateView):
model = User
template_name = 'user/profile-settings.html'
form_class = UserEditForm
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
self.object = self.get_object()
if request.user != self.object:
raise Http404()
return super().dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
# it's magic *-*-*-*-*
if 'photo' in request.FILES:
photo_fp = request.FILES.pop('photo')[0]
fname = photo_fp.name
photo = Image.open(photo_fp)
lowest_side = min(photo.size)
horizontal_padding = (lowest_side - photo.size[0]) / 2
vertical_padding = (lowest_side - photo.size[1]) / 2
photo = photo.crop(
(
-horizontal_padding,
-vertical_padding,
photo.size[0] + horizontal_padding,
photo.size[1] + vertical_padding
)
)
if photo.size[0] > 512:
photo = photo.resize((512, 512,))
buffer = BytesIO()
ext = splitext(fname)[1][1:].upper()
if ext == 'JPG':
ext = 'JPEG'
photo.save(buffer, ext)
self.object.photo.save(fname, buffer)
buffer.close()
if not request.POST._mutable:
request.POST._mutable = True
old_password = request.POST.pop('old_password')[0]
new_password1 = request.POST.pop('new_password1')[0]
new_password2 = request.POST.pop('new_password2')[0]
if old_password:
if request.user.check_password(old_password) and new_password1 == new_password2:
request.user.set_password(new_password1)
request.user.save()
login(request, request.user)
else:
messages.error(request, 'Неверный пароль.')
messages.info(request, 'Данные сохранены.')
return super().post(request, *args, **kwargs)
def get_success_url(self):
return reverse('user-edit-profile', args=[self.object.id])